【问题标题】:lambda inside subscript iterator下标迭代器内的 lambda
【发布时间】:2017-01-17 15:04:20
【问题描述】:

在下标运算符中包含 lambda 似乎不适用于 g++ 和 clang。

这是实现错误还是 c++ 标准中的“不愉快”规则?

例子:

class A
{   
    public:
        template<typename T> void operator[](T) {}
        template<typename T> void operator()(T) {}
};  

int main()
{   
    A a;
    a[ [](){} ];    // did not compiler: see error message
    a( [](){} );    // works as expected
} 

错误:

main.cpp:13:6: error: two consecutive '[' shall only introduce an attribute before '[' token
     a[ [](){} ];
      ^   
main.cpp:13:15: error: expected primary-expression before ']' token
     a[ [](){} ];

我知道属性以“[[”开头,但我想知道“[[”(带有一个或多个空格)也可以这样工作:

 void func( int x [ [gnu::unused] ] ) {} // compiles fine! :-(

【问题讨论】:

    标签: c++ c++11 lambda attributes language-lawyer


    【解决方案1】:

    您必须将 lambda 括在括号中。否则编译器会将两个[[ 视为引入一个属性。

    使用 operator delete 可能会出现类似的问题。例如你必须写

    delete ( [] { return ( new int() ); }() );
    

    delete [] ( [] { return ( new int[10] ); }() );
    

    也就是说,您必须将 lambda 括在括号中。

    【讨论】:

    • 很高兴从其他背景中看到这些奇怪的例子。谢谢
    【解决方案2】:

    这在 [dcl.attr.grammar] 中有介绍。有两个连续的[ 是一个属性,所以你必须用括号括起来或做其他事情来明确你的意图:

    两个连续的左方括号标记仅在引入属性说明符时或在其中出现 attribute-argument-clausebalanced-token-seq[注:如果出现两个连续的左方括号 在不允许使用 属性说明符 的情况下,程序是非良构的,即使括号匹配替代语法产生式——尾注] [示例:

    int p[10];
    void f() {
      int x = 42, y[5];
      int(p[[x] { return x; }()]);   // error: invalid attribute on a nested
                                     // declarator-id and not a function-style cast of
                                     // an element of p.
      y[[] { return 2; }()] = 2;     // error even though attributes are not allowed
                                     // in this context.
      int i [[vendor::attr([[]])]];  // well-formed implementation-defined attribute.
    }
    

    ——结束示例]

    【讨论】:

    • “连续”的意思是有或没有额外的空格?
    • @Klaus C++ 对空格不敏感。 &gt;&gt; 是一个例外,因为它被视为令牌,但没有 [[ 令牌。
    • 昨天得知template &lt;&gt; double B::var&lt;double&gt;=1.123; 无效,但template &lt;&gt; double B::var&lt;double&gt; =1.123;有效。只有一个空格... :-)
    • @Klaus &gt;= 也是一个令牌。
    【解决方案3】:

    你可以用括号括起来参数

    a[ ( [](){} ) ];
    

    【讨论】:

    • 现在知道第一次在这里的情况:-):很高兴看到解决方法。但是有人知道这是标准的意图吗?将属性的开头修复为 '[[' 将消除该问题。这就是为什么我问它是被破坏的实现还是“不幸”的标准。
    猜你喜欢
    • 2014-10-28
    • 2017-11-11
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-01-16
    相关资源
    最近更新 更多