C++ Lambdas: Difference between “mutable” and capture-by-reference

后端 未结 1 363
醉酒成梦
醉酒成梦 2021-01-30 08:19

In C++ you can declare lambdas for example like this:

int x = 5;
auto a = [=]() mutable { ++x; std::cout << x << \'\\n\'; };
auto b = [&]()               


        
相关标签:
1条回答
  • 2021-01-30 09:03

    What is happening

    The first will only modify its own copy of x and leave the outside x unchanged. The second will modify the outside x.

    Add a print statement after trying each:

    a();
    std::cout << x << "----\n";
    b();
    std::cout << x << '\n';
    

    This is expected to print:

    6
    5
    ----
    6
    6
    

    Why

    It may help to consider that lambda

    [...] expressions provide a concise way to create simple function objects

    (see [expr.prim.lambda] of the Standard)

    They have

    [...] a public inline function call operator [...]

    which is declared as a const member function, but only

    [...] if and only if the lambda expression’s parameter-declaration-clause is not followed by mutable

    You can think of as if

        int x = 5;
        auto a = [=]() mutable { ++x; std::cout << x << '\n'; };
    
    ==>
    
        int x = 5;
    
        class __lambda_a {
            int x;
        public:
            __lambda_a () : x($lookup-one-outer$::x) {}
            inline void operator() { ++x; std::cout << x << '\n'; }     
        } a;
    

    and

        auto b = [&]()         { ++x; std::cout << x << '\n'; };
    
    ==>
    
        int x = 5;
    
        class __lambda_b {
            int &x;
        public:
            __lambda_b() : x($lookup-one-outer$::x) {}
            inline void operator() const { ++x; std::cout << x << '\n'; }         
            //                     ^^^^^
        } b;
    

    Q: But if it is a const function, why can I still change x?

    A: You are only changing the outside x. The lambda's own x is a reference, and the operation ++x does not modify the reference, but the refered value.

    This works because in C++, the constness of a pointer/reference does not change the constness of the pointee/referencee seen through it.

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