不知怎的,我不知道如何扩展可变的模板参数包.以下代码有什么问题?
#include <iostream> template <typename T> struct print_one { static void run(const T& t) { std::cout << t << ' '; } }; template<typename... Args> void print_all(Args&&... args) { // the next line doesn't compile: print_one<Args>::run(std::forward<Args>(args))...; } int main() { print_all(1.23,"foo"); }
Clang说,Expression包含未展开的参数包的Args和args.为什么?
解决方法
…必须在函数调用括号内进行:
print_one<Args>::run(std::forward<Args>(args)...);
显然,这不会对你的函数只有一个参数,所以你需要找到一种方法来扩展调用到函数调用或其他允许的结构:
// constructing a dummy array via uniform initialization // the extra 0 at the start is to make it work when the pack is empty int dummy[]{0,(print_one<Args>::run(std::forward<Args>(args)),0)...}; // or,if your compiler doesn't support uniform initialization int dummy[] = {0,calling a dummy function template<typename... Args> void dummy(Args...) {} dummy((print_one<Args>::run(std::forward<Args>(args)),0)...); // or,constructing a temporary dummy object struct dummy { dummy(std::initializer_list<int>) {} }; dummy{(print_one<Args>::run(std::forward<Args>(args)),constructing a temporary initializer list std::initializer_list<int>{(print_one<Args>::run(std::forward<Args>(args)),0)...};
请注意,使用逗号运算符将print_one的void返回值转换为适合放置在参数列表或初始化程序表达式中的值.
初始化器列表表单优先于函数调用表单,因为它们(应该是)排序的LTR函数调用参数不是.
参数包扩展的形式可以由14.5.3 [temp.variadic]覆盖:
4 – […] Pack expansions can occur in the following contexts:
- […]
您的原始代码是非法的,因为尽管在文本上可能会出现一个由多个逗号运算符表达式组成的语句,这不是14.5.3:4允许的上下文.