C ++:在构造函数中使用参数包?

c++ : using parameter pack in constructors?

本文关键字:参数 构造函数      更新时间:2023-10-16
#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);
}

上面的代码编译并运行良好。但:

// (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);
}

编译失败,并显示消息:

main.cpp:在函数 'int main((' 中: main.cpp:64:18: 错误: 无匹配 用于调用 'F::F(int, bool, int(' 的函数 F(4,真,1(;

使用当前代码,F<A>的实例化会使Args模板参数为空,这意味着构造函数只有a参数,而不是args

似乎您只希望构造函数具有模板参数包,而不是整个类:

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

你把类变成了一个模板,而不是构造函数。

但只有构造函数"知道"模板参数应该是什么,因为这些参数是从构造函数参数推导出来的。

那行不通。

相反,您可以将构造函数设置为模板,而不是类。

根据您的需要,它应该是:

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);
}

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);
}