在下面的代码中,我在初始化列表中展开参数包,同时在每个元素上调用函数DoSomethingReturnInt
。在下面,我尝试做一些看似类似的尝试,并在每个元素上调用DoSomething
,但得到编译器错误。这根本不可能,或者我只是需要稍微修改它来完成这个?在我看来,这样的事情应该是可能的。
template <class T>
int DoSomethingReturnInt(T&& t)
{}
template <class T>
void DoSomething(T&& t)
{}
template <class... T>
void variadic(T&&... args)
{
int arr[] = { DoSomethingReturnInt(args)... }; //Compiles OK
DoSomething(args)...; //error: parameter packs not expanded with '...'
}
int main()
{
variadic("Testing", "one", 2.0, 3);
}
答案 0 :(得分:4)
这不是参数包扩展的有效位置。有关包扩展的有效上下文包含在draft C++ standard部分14.5.3
可视化模板中,其中包含:
包扩展由模式和省略号组成 其实例化产生零个或多个实例化 列表中的模式(如下所述)。模式的形式取决于 在扩张发生的背景下。包装扩展可以 发生在以下情况中:
- 在函数参数包中 (8.3.5);模式是没有的参数声明 省略号。
- 在作为包扩展的模板参数包(14.1)中:
- 如果模板参数包是参数声明;模式是参数声明 没有省略号;
- 如果模板参数包是带有template-parameter-list的type-parameter;模式是 没有省略号的相应类型参数。
- 在初始化列表中(8.5);模式是初始化子句。
- 在基本说明符列表中(第10条);模式是基本说明符。
- 在mem-initializer-list(12.6.2)中;该模式是一个mem-initializer。
- 在template-argument-list(14.3)中;模式是模板参数。
- 在动态异常规范(15.4)中;模式是一个类型ID。
- 在属性列表(7.6.1)中;模式是一个属性。
- 在alignment-specifier(7.6.2)中;模式是没有省略号的alignment-specifier。
- 在捕获列表(5.1.2)中;模式是捕获。
- 在sizeof ...表达式中(5.3.3);模式是一个标识符。
Parameter pack的cppreference部分也介绍了这一点。
答案 1 :(得分:4)
您可以在此处使用逗号运算符。
int dummy[] = { (DoSomething(args), 0)... };
编辑:如果你不喜欢逗号运算符“滥用”,可能是lambda?
int dummy[] = { []() { DoSomething(args); return 0; }()... };
请注意,gcc4.9似乎无法处理这个问题,但是clang会做得很好。