SHAMELESS COPY [由其来源批准]
参数包只能在严格定义的上下文列表中扩展,而operator,
不是其中之一。换句话说,不可能使用包扩展来生成由一系列由operator分隔的子表达式组成的表达式,
。
经验法则是“扩展可以生成由-分隔的,
模式的列表,其中,
是列表定界符。” 运算符,
不会在语法意义上构造列表。
要为每个参数调用一个函数,可以使用递归(这是可变参数模板程序员框中的主要工具):
#include <utility>
template<typename T>
void foo(T &&t){}
template<typename Arg0, typename Arg1, typename ... Args>
void foo(Arg0 &&arg0, Arg1 &&arg1, Args &&... args){
foo(std::forward<Arg0>(arg0));
foo(std::forward<Arg1>(arg1), std::forward<Args>(args)...);
}
auto main() -> int{
foo(1, 2, 3, "3");
}
有用的未复制信息
您可能没有在此答案中看到的另一件事是使用说明&&
符和std::forward
。在C ++中,说明&&
符可能表示以下两种情况之一:rvalue-references或通用引用。
我不会涉及右值引用,而是会介绍使用可变参数模板的人。通用引用是天赐之物。
完美转发
std::forward
通用引用的用途之一是将类型完美地转发到其他函数。
在您的示例中,如果我们将传递int&
给foo2
它,则int
由于foo2
模板推导后生成函数的签名,它会被自动降级为;如果您想将其转发arg
给另一个可以通过引用对其进行修改的函数,则会得到不希望的结果(该变量将不会更改),因为foo2
它将传递对通过传递int
给它的临时文件的引用。为了解决这个问题,我们指定了一个转发函数以对变量(rvalue或lvalue)进行任何类型的引用。然后,要确保我们传递在转发函数中传递的确切类型,则只能使用std::forward
那我们允许降级类型吗?因为我们现在才是最重要的时刻。
如果需要,请阅读有关通用参考和完善转发的更多信息;Scott Meyers作为资源非常棒。
Args
是空的怎么办?