g++ won't allow generalized capture of const object by reference in lambda?

前端 未结 2 1566
清酒与你
清酒与你 2020-12-11 14:48

This is rejected by g++ (4.9.3 and 5.2.0), but is accepted by clang 3.5.0:

int main() { 
    const int ci = 0;
    auto lambda = [ &cap = ci ]() { };
}
<         


        
相关标签:
2条回答
  • 2020-12-11 15:28

    Your code is valid. §5.1.2/11 goes

    An init-capture behaves as if it declares and explicitly captures a variable of the form
    auto init-capture ;
    whose declarative region is the lambda-expression’s compound-statement […]

    Now, clearly, declaring

    auto &cap = ci;
    

    and capturing cap is fine. That is,

    int main() { 
        const int ci = 0;
        auto &cap = ci;
        auto lambda = [&cap]() { };
    }
    

    compiles with GCC. Apart from the declarative region and lifetime of cap, there is no difference between this snippet and yours, thus GCC is incorrect.
    This bug has already been reported as #66735, with a similar example:

    int x = 0;
    auto l = [&rx = static_cast<const int&>(x)] {};
    
    0 讨论(0)
  • 2020-12-11 15:30

    This looks similar to gcc bug: [C++14] lambda init-capture fails for const references which says:

    This code fails to compile:

    int main() {
        int x = 0;
        auto l = [&rx = static_cast<const int&>(x)]() {};
    }
    

    The error message is:

    test.cpp:3:14: error: binding 'const int' to reference of type 'int&' discards qualifiers

    auto l = [&rx = static_cast<const int&>(x)]() {
    

    But according to [expr.prim.lambda]/11 rx should be captured as auto &rx = static_cast(x), that is as const int&.

    the bug report references [expr.prim.lambda]/11 which says:

    An init-capture behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;” whose declarative region is the lambda-expression’s compound-statement, except that[...]

    0 讨论(0)
提交回复
热议问题