Search code examples
c++argumentsvariadicparameter-pack

c++ : using parameter pack in constructors?


#include <iostream>

class A 
{
    public: 

    A(bool b, int i)
        : b_(b) , i_(i) {}

    void print()
    {
        std::cout << b_ << " " << i_ << "\n"; 
    }

    private:

        bool b_;
        int i_;
};

class B 
{
    public: 

    B(double d)
        : d_(d) {}

    void print()
    {
        std::cout << d_ << "\n"; 
    }

    private:

        double d_;
};

template<class T=A, typename ... Args>
void f(int a, Args ... args)
{
    std::cout << a << std::endl;
    T t(args...);
    t.print();
}

int main()
{
    f(1,false,3);
    f<A>(2,true,1);
    f<B>(3,2.0);
}

The code above compiles and runs fine. But:

// (class A and B declared as above)   

template<class T, typename ... Args>
class F 
{
 public:
  F(int a, Args ... args)
  {
    std::cout << a << std::endl;
    T t(args...);
    t.print();
  }
};

int main()
{
    F<A>(4,true,1);
    F<B>(5,2.0);
}

fails to compile with message :

main.cpp: In function ‘int main()’: main.cpp:64:18: error: no matching function for call to ‘F::F(int, bool, int)’ F(4,true,1);


Solution

  • With your current code, your instantiation of F<A> makes the Args template argument empty, which means the constructor only have the a argument, not args.

    It seems that you want only the constructor to have a template parameter pack, not the whole class:

    template<class T>
    class F 
    {
     public:
      template<typename ... Args>
      F(int a, Args ... args)
      {
        std::cout << a << std::endl;
        T t(args...);
        t.print();
      }
    };