Can a lambda capturing nothing access global variables?

后端 未结 3 2001
走了就别回头了
走了就别回头了 2021-02-05 04:07
int n;    
int main()
{
    [](){ n = 0; }(); // clang says \"ok\"

    int m;
    [](){ m = 0; }(); // clang says \"not ok\"
}

I just wonder:

相关标签:
3条回答
  • 2021-02-05 04:49

    Actually the [](){ n = 10; }(); doesn't capture anything, it uses the global variable instead.

    int n;    
    int main()
    {
        [](){ n = 10; }(); // clang says "ok"
        std::cout << n; // output 10
    }
    

    See capture-list in Explaination

    capture-list - a comma-separated list of zero or more captures, optionally beginning with a capture-default.

    Capture list can be passed as follows (see below for the detailed description):

    • [a,&b] where a is captured by copy and b is captured by reference.
    • [this] captures the current object (*this) by reference
    • [&] captures all automatic variables used in the body of the lambda by reference and current object by reference if exists
    • [=] captures all automatic variables used in the body of the lambda by copy and current object by reference if exists
    • [ ] captures nothing
    0 讨论(0)
  • 2021-02-05 04:54

    Global, static and const variables are accessed by default:

    #include <iostream>
    
    int n;    
    int main()
    {
        [](){ n = 10; }();
        std::cout << n << std::endl;
        static int m = 1;
        [](){ m = 100; }();
        std::cout << m << std::endl;
        const int l = 200;
        [](){ std::cout << l << std::endl; }();
    }
    
    0 讨论(0)
  • 2021-02-05 05:03

    Yes, sure. Normal name lookup rules apply.

    [expr.prim.lambda]/7 ... for purposes of name lookup ... the compound-statement is considered in the context of the lambda-expression.

    Re: why local variables are treated differently from global ones.

    [expr.prim.lambda]/13 ... If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses (3.2) this or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.

    [expr.prim.lambda]/9 A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression... The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the innermost enclosing function and its parameters.

    In your example, m is a variable with automatic storage duration from the lambda's reaching scope, and so shall be captured. n is not, and so doesn't have to be.

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