c++c++11lambdaconstantsfunction-call-operator

Why is a lambda's call-operator implicitly const?


I have a small "lambda expression" in the below function:

int main()
{
    int x = 10;
    auto lambda = [=] () { return x + 3; };
}

Below is the "anonymous closure class" generated for the above lambda expression.

int main()
{
    int x = 10;

    class __lambda_3_19
    {
        public: inline /*constexpr */ int operator()() const
        {
            return x + 3;
        }

        private:
            int x;

        public: __lambda_3_19(int _x) : x{_x}
          {}

    };

    __lambda_3_19 lambda = __lambda_3_19{x};
}

The closure's "operator()" generated by the compiler is implicitly const. Why did the standard committee make it const by default?


Solution

  • From cppreference

    Unless the keyword mutable was used in the lambda-expression, the function-call operator is const-qualified and the objects that were captured by copy are non-modifiable from inside this operator()

    In your case, there is nothing that, captured by copy, is modifiable.

    I suppose that, if you write something as

    int x = 10;
    
    auto lambda = [=] () mutable { x += 3; return x; };
    

    the const should disappear

    -- EDIT --

    The OP precise

    I already knew that adding mutable will solve the issue. The question is that I want to understand the reason behind making the lambda immutable by default.

    I'm not a language lawyer but this seems me obvious: if you make operator() not const, you can't make something as

    template <typename F>
    void foo (F const & f)
     { f(); }
    
    // ...
    
    foo([]{ std::cout << "lambda!" << std::endl; });
    

    I mean... if operator() isn't const, you can't use lambdas passing they as const reference.

    And when isn't strictly needed, should be an unacceptable limitation.