在模板函数内使用lambda内括号时,左括号不正确匹配

Mee*_*ons 2 c++ lambda visual-c++-2013

使用Visual C++ 2013,以下代码产生一个奇怪的编译错误:

/// header.h
class Test
{
public:
    template <typename Func>
    void operator[](Func f)
    {
        f();
    }
};

template <typename T>
void funct()
{
    Test t;
    t[[](){; }];    // line 16 // The same error with t[ ([](){; }) ];
}

/// main.cpp
int main()
{
    funct<int>();
    // funct();
}
Run Code Online (Sandbox Code Playgroud)

错误:

1>c:\path\to\header.h(16): error C2958: the left bracket '[' found at 'e:\path\to\header.h(16)' was not matched correctly
1>c:\path\to\header.h(16): error C2059: syntax error : ']'
1>c:\path\to\header.h(17): error C2059: syntax error : '}'
1>c:\path\to\header.h(17): error C2143: syntax error : missing ';' before '}'
Run Code Online (Sandbox Code Playgroud)


当lambda函数体没有任何语句时,不会发生此错误:

template <typename T>
void funct()
{
    Test t;
    t[[](){ }];    // line 16 // No semicolon - No statement - No errors
}
Run Code Online (Sandbox Code Playgroud)


或者当函数不是模板时:

// Ordinary function - No errors
void funct()
{
    Test t;
    t[[](){; }];    // line 16
}
Run Code Online (Sandbox Code Playgroud)


我想我在这个编译器中发现了一个错误.但是,如果有人知道如何在没有错误的情况下编写它并且不使用变量来保存lambda函数,那就太好了.

Col*_*mbo 5

VC++正确拒绝了这段代码,但由于错误的原因 - 这是一个错误.根据[dcl.attr.grammar]/6,这是不正确的:

只有在引入属性说明符时,才会出现两个连续的左方括号标记.[ 注意: 如果出现两个连续的左方括号,其中不允许使用属性说明符,即使括号与替代语法生成匹配 ,程序也会格式不正确.- 尾注 ] [ 示例:

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.
}
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

因此,请尝试将lambda表达式括在两个parantheses中,如下所示.

t[ ([](){; }) ];
Run Code Online (Sandbox Code Playgroud)

或写

auto&& closure = [](){; };
t[closure]; // move here if correct value category is desired
Run Code Online (Sandbox Code Playgroud)