#include <iostream> template<typename... Ts> void expander(Ts&&... ts) { using expand = int[]; (void)expand{0,(std::forward<Ts>(ts)(),0)...}; } void f() { std::cout << __PRETTY_FUNCTION__ << std::endl; } int main() { expander(f,f); }
Live on Coliru@H_403_5@
我们可以在不引入typedef的情况下这样做吗?如果我直接尝试@H_403_5@
(void)int[]{0,0)...};
gcc / clang吐了出来@H_403_5@
error: expected primary-expression before ‘int’@H_403_5@
如果我尝试括号,代码编译但我相信它是非标准的:@H_403_5@
warning: ISO C++ forbids compound-literals [-Wpedantic]@H_403_5@
解决方法
(void)int[]{0,0)...};
您正在尝试使用功能表示法转换来创建临时数组.这是行不通的,因为该语言只允许函数表示法与simple-type-specifier或typename-specifier一起使用.@H_403_5@
从[expr.type.conv]/3起@H_403_5@
Similarly,a simple-type-specifier or typename-specifier followed by a braced-init-list creates a temporary object of the specified type direct-list-initialized (8.5.4) with the specified braced-init-list,and its value is that temporary object as a prvalue.@H_403_5@
如果你在[dcl.type.simple]下查找simple-type-specifier的定义,它不包含带数组括号的任何东西.事实上,它甚至不包含任何超过一个单词的内容.这就是编写int(1)有效的原因,但是signed int(1)不是.@H_403_5@
因此,使用C 11/14,您需要一个typedef或声明一个数组变量.但是,使用C 1z编译器,您可以使用折叠表达式并避免两者@H_403_5@
template<typename... Ts> void expander(Ts&&... ts) { (void(std::forward<Ts>(ts)()),...); }