c – Clang和二进制折叠表达式 – 空参数包的诅咒

特别是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) {
                 ^

…而我的输出只有—- foo(1,3);不再输出了!

克朗是否被未来标准的邪恶力量诅咒,是否有错误,或现在坐在椅子上的问题?

解决方法

当使用功能符号转换转换为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

由于括号不需要作为转换表达式的一部分,所以该用法不应该产生警告,更重要的是,它应该导致打印参数.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...