Clang和二进制折叠表达式 - 空参数包的诅。 [英] Clang and the binary fold expressions — The curse of the empty parameter pack

查看:185
本文介绍了Clang和二进制折叠表达式 - 空参数包的诅。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

特别是Clang 3.6.0,目前由Coliru托管。

Specifically Clang 3.6.0, the one currently hosted by Coliru.

所有这些代码片段都来自:

All these snippets are called from :

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;
              ^

所以我试着在表达式上加括号:

So I tried putting parentheses around the expression :

(std::cout << ... << args);

它可以工作,但会触发警告:

It works, but triggers a warning :

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

So I tried to discard the value of the expression with a function-style cast to 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:

So I tried with a C-cast instead :

(void)(std::cout << ... << args);

但是:

main.cpp:6:18: warning: unused parameter 'args' [-Wunused-parameter]
void foo(Args... args) {
                 ^

... and my output is only ---- foo(1,2,3); 不再输出了!

... and my output is only ---- : foo(1, 2, 3); doesn't output anymore !

俚语被未来标准的邪恶力量诅咒,它有一个bug,还是现在坐在我的椅子上的问题?

Is Clang cursed by an evil force from future standards, does it have a bug, or is the problem sitting on my chair right now ?

推荐答案

当转换到 void 时,需要一组额外的括号函数符号转换,否则括号被视为转换表达式的一部分,而不是折叠表达式。 折叠表达式语法本身需要一组括号。

You need an extra set of parentheses when casting to void using the functional notation cast, otherwise the parentheses are considered part of the cast expression instead of the fold expression. The fold expression syntax itself requires a set of parentheses.

以下所有工作都不会产生任何警告:

All of the following work without producing any warnings:

void((std::cout << ... << args));
(void)((std::cout << ... << args));

或者只需调用一些 ostream 成员函数避免未使用的结果警告

Or just call some ostream member function to avoid the unused result warning

(std::cout << ... << args).flush();






在下面的注释中,与(void)(std :: cout 的行为看起来像一个铛bug。转换符号的语法在 5.4 [expr.cast]


As T.C. mentions in the comments below, the behavior with (void)(std::cout << ... << args); seems like a clang bug. The syntax for a cast notation is specified in 5.4 [expr.cast]


cast-expression

   一元表达式

  

cast-expression:
  unary-expression
  ( type-id ) cast-expression

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

Since parentheses are not required as part of the cast expression, that usage shouldn't be producing warnings, and more importantly, it should result in printing the arguments.

这篇关于Clang和二进制折叠表达式 - 空参数包的诅。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆