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

  • A+

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?


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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: