type of reference-captured object inside lambda

后端 未结 1 954
醉梦人生
醉梦人生 2021-01-04 00:28

The following code works with gcc

#include 

int main() {
    std::map dict;
    const auto lambda = [&]()
    {
        de         


        
相关标签:
1条回答
  • 2021-01-04 01:02

    There is no special rule regarding non parenthesized applications of decltype (ie. [expr.prim.lambda]/20 does not apply). So we just fall back to the usual definition of decltype, which mandates that if the operand is an id-expression, the yielded type is just the declared type of the entity, and that's not a reference type. Hence VC++ is wrong.

    NB: it doesn't matter whether dict is captured or not, because ¶17:

    Every id-expression within the compound-statement of a lambda-expression that is an odr-use (3.2) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type. [ Note: An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. Furthermore, such an id-expression does not cause the implicit capture of the entity. — end note ]

    decltype never odr-uses any of its operands or suboperands. This rule actually gets pretty problematic at times, e.g. as shown in core issue 958:

    int f (int&);
    void* f (const int&);
    
    int main()
    {
       int i;
       [=] ()-> decltype(f(i)) { return f(i); };
    }
    

    Here, decltype(f(i)) uses the non-const i from the enclosing scope. However, since the lambda isn't mutable, the i in the body is actually const, hence the trailing-return-type is incorrect. CWG concluded this arises too infrequently to be worth solving.

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