0
#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);

Vince
  • 3,979
  • 10
  • 41
  • 69

3 Answers3

3

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();
  }
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

You made the class a template, not the constructor.

But only the constructor "knows" what the template arguments should be, because those are deduced from the constructor arguments.

That doesn't work.

Instead, you can make the constructor a template, not the class.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
1

Depending of your needs, it should be:

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, bool, int>(4,true,1);
    F<B, double>(5,2.0);
}

or

template<class T>
class F 
{
 public:
  template <typename ... Args>
  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);
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302