在可变参数模板的上下文中,省略号...
用于解包模板参数包,如果它出现在表达式的右侧(暂时称为此表达式模式),或者如果它出现在左侧,则它是一个包参数姓名:
...thing // pack : appears as template arguments
thing... // unpack : appears when consuming the arguments
规则是重复左侧的任何模式- 解压缩的模式(现在称为表达式)用逗号分隔。...
,
通过一些例子可以最好地理解它。假设你有这个函数模板:
template<typename ...T> //pack
void f(T ... args) //pack
{
// here are unpack patterns
g( args... ); //pattern = args
h( x(args)... ); //pattern = x(args)
m( y(args...) ); //pattern = args (as argument to y())
n( z<T>(args)... ); //pattern = z<T>(args)
}
T
现在,如果我将此函数调用为传递{int, char, short}
,则每个函数调用都扩展为:
g( arg0, arg1, arg2 );
h( x(arg0), x(arg1), x(arg2) );
m( y(arg0, arg1, arg2) );
n( z<int>(arg0), z<char>(arg1), z<short>(arg2) );
在您发布的代码中,std::forward
遵循n()
函数调用说明的第四种模式。
x(args)...
注意和上面的区别y(args...)
!
您也可以使用...
以下方式初始化数组:
struct data_info
{
boost::any data;
std::size_t type_size;
};
std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}
扩展为:
std::vector<data_info> v
{
{arg0, sizeof(int)},
{arg1, sizeof(char)},
{arg2, sizeof(short)}
};
我刚刚意识到一个模式甚至可以包含访问说明符,例如public
,如下例所示:
template<typename ... Mixins>
struct mixture : public Mixins ... //pattern = public Mixins
{
//code
};
在此示例中,模式扩展为:
struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN
也就是说,从所有基类公开mixture
派生。
希望有帮助。