特别是Clang 3.6.0,目前由Coliru主办.
所有这些片段都来自:
int main() { foo(); std::cout << "\n----\n"; foo(1,2,3); }
以下代码:
template <class... Args> void foo(Args... args) { std::cout << ... << args; }
触发以下编译错误:
main.cpp:7:17: error: expected ';' after expression std::cout << ... << args; ^ ; main.cpp:7:15: error: expected expression std::cout << ... << args; ^
所以我试着用括号括起来:
(std::cout << ... << args);
它有效,但会触发警告:
main.cpp:7:6: warning: expression result unused [-Wunused-value] (std::cout << ... << args); ^~~~~~~~~ main.cpp:11:5: note: in instantiation of function template specialization 'foo<>' requested here foo(); ^
所以我试图把一个函数样式的表达式的值丢弃为void:
void(std::cout << ... << args);
但是:
main.cpp:7:20: error: expected ')' void(std::cout << ... << args); ^ main.cpp:7:9: note: to match this '(' void(std::cout << ... << args); ^
我也试过一个static_cast,结果相同.
所以我试着用C-cast:
(void)(std::cout << ... << args);
但是之后 :
main.cpp:6:18: warning: unused parameter 'args' [-Wunused-parameter] void foo(Args... args) { ^
克朗是否被未来标准的邪恶力量诅咒,是否有错误,或现在坐在椅子上的问题?
解决方法
当使用功能符号转换转换为void时,需要一组额外的括号,否则括号将被视为转换表达式的一部分,而不是折叠表达式.
fold expression syntax本身需要一组括号.
以下所有工作不产生任何警告:
void((std::cout << ... << args)); (void)((std::cout << ... << args));
或者只是调用一些ostream成员函数来避免未使用的结果警告
(std::cout << ... << args).flush();
正如T.C.在下面的评论中提到,(void)(std :: cout<< ...<< args)的行为;好像是一个笨蛋转换符号的语法在5.4 [expr.cast]中指定
cast-expression:
unary-expression
( type-id ) cast-expression
由于括号不需要作为转换表达式的一部分,所以该用法不应该产生警告,更重要的是,它应该导致打印参数.