Why is a lambda's call-operator implicitly const?
up vote
13
down vote
favorite
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?
c++ c++11 lambda const function-call-operator
|
show 16 more comments
up vote
13
down vote
favorite
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?
c++ c++11 lambda const function-call-operator
9
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
3
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
1
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
2
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If theoperator()
function is marked asconst
then that's not possible.
– Some programmer dude
2 days ago
2
Its the wrong way around that we have to declare member functions explicitly asconst
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function whenauto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.
– user463035818
2 days ago
|
show 16 more comments
up vote
13
down vote
favorite
up vote
13
down vote
favorite
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?
c++ c++11 lambda const function-call-operator
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?
c++ c++11 lambda const function-call-operator
c++ c++11 lambda const function-call-operator
edited 2 days ago
max66
32.8k63660
32.8k63660
asked 2 days ago
gurram
17711
17711
9
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
3
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
1
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
2
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If theoperator()
function is marked asconst
then that's not possible.
– Some programmer dude
2 days ago
2
Its the wrong way around that we have to declare member functions explicitly asconst
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function whenauto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.
– user463035818
2 days ago
|
show 16 more comments
9
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
3
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
1
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
2
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If theoperator()
function is marked asconst
then that's not possible.
– Some programmer dude
2 days ago
2
Its the wrong way around that we have to declare member functions explicitly asconst
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function whenauto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.
– user463035818
2 days ago
9
9
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
3
3
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
1
1
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
2
2
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If the
operator()
function is marked as const
then that's not possible.– Some programmer dude
2 days ago
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If the
operator()
function is marked as const
then that's not possible.– Some programmer dude
2 days ago
2
2
Its the wrong way around that we have to declare member functions explicitly as
const
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function when auto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.– user463035818
2 days ago
Its the wrong way around that we have to declare member functions explicitly as
const
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function when auto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.– user463035818
2 days ago
|
show 16 more comments
3 Answers
3
active
oldest
votes
up vote
8
down vote
accepted
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 thisoperator()
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.
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employstd::reference_wrapper
as needed.
– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for theconst
qualifier ofstd::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require aconst
qualifier for const-ness.() const { ... }
looks more consistent to me.
– liliscent
2 days ago
add a comment |
up vote
18
down vote
Found this paper by Herb Sutter at open-std.org which discusses this matter.
The odd couple: Capture by value’s injected const and quirky mutable
Consider this strawman example, where the programmer captures a local variable by value and tries to modify the captured value (which is a member variable of the lambda object):
int val = 0;
auto x = [=]( item e ) // look ma, [=] means explicit copy
{ use( e, ++val ); }; // error: count is const, need ‘mutable’
auto y = [val]( item e ) // darnit, I really can’t get more explicit
{ use( e, ++val ); }; // same error: count is const, need ‘mutable’
This feature appears to have been added out of a concern that the user might not realize he got a copy, and in particular that since lambdas are copyable he might be changing a different lambda’s copy.
The above quote and example indicate why the Standards Committee might have made it const
by default and required mutable
to change it.
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda tostd::sort
, then trying to use it again outside ofstd::sort
(or in a second call tostd::sort
) wouldn't show any of the changes made by the calls instd::sort
, right?
– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
add a comment |
up vote
0
down vote
I think, it is simply to avoid confusion when a variable inside a lambda refer not to what was originally captured. Lexically such a variable is as if in scope of its "original". Copying is mainly to allow to extend the lifetime of object. When a capture is not by copy it refers to original and modifications are applied to the original, and there is no confusion because of two different objects (one of which is implicitly introduced), and it is allowed by lambda's const function call operator.
New contributor
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
accepted
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 thisoperator()
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.
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employstd::reference_wrapper
as needed.
– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for theconst
qualifier ofstd::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require aconst
qualifier for const-ness.() const { ... }
looks more consistent to me.
– liliscent
2 days ago
add a comment |
up vote
8
down vote
accepted
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 thisoperator()
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.
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employstd::reference_wrapper
as needed.
– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for theconst
qualifier ofstd::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require aconst
qualifier for const-ness.() const { ... }
looks more consistent to me.
– liliscent
2 days ago
add a comment |
up vote
8
down vote
accepted
up vote
8
down vote
accepted
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 thisoperator()
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.
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 thisoperator()
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.
edited 2 days ago
answered 2 days ago
max66
32.8k63660
32.8k63660
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employstd::reference_wrapper
as needed.
– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for theconst
qualifier ofstd::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require aconst
qualifier for const-ness.() const { ... }
looks more consistent to me.
– liliscent
2 days ago
add a comment |
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employstd::reference_wrapper
as needed.
– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for theconst
qualifier ofstd::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require aconst
qualifier for const-ness.() const { ... }
looks more consistent to me.
– liliscent
2 days ago
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employ
std::reference_wrapper
as needed.– Deduplicator
2 days ago
Passing a function-object by constant reference is strange. The standard-library (nearly?) always passes callables by value, expecting the caller to employ
std::reference_wrapper
as needed.– Deduplicator
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
@Deduplicator - I suppose depends on circumstances. Generally speaking, I don't see a good reason to impose that a callable is modifiable when the called method doens't change the object itself.
– max66
2 days ago
1
1
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for the
const
qualifier of std::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require a const
qualifier for const-ness. () const { ... }
looks more consistent to me.– liliscent
2 days ago
@Deduplicator Although passing by value or forwarding-reference is more common, passing const ref isn't really strange. I would think this answer is the reason for the
const
qualifier of std::function
. But for a lambda, it's not convincing, since lambda can certainly be mutable by default, and require a const
qualifier for const-ness. () const { ... }
looks more consistent to me.– liliscent
2 days ago
add a comment |
up vote
18
down vote
Found this paper by Herb Sutter at open-std.org which discusses this matter.
The odd couple: Capture by value’s injected const and quirky mutable
Consider this strawman example, where the programmer captures a local variable by value and tries to modify the captured value (which is a member variable of the lambda object):
int val = 0;
auto x = [=]( item e ) // look ma, [=] means explicit copy
{ use( e, ++val ); }; // error: count is const, need ‘mutable’
auto y = [val]( item e ) // darnit, I really can’t get more explicit
{ use( e, ++val ); }; // same error: count is const, need ‘mutable’
This feature appears to have been added out of a concern that the user might not realize he got a copy, and in particular that since lambdas are copyable he might be changing a different lambda’s copy.
The above quote and example indicate why the Standards Committee might have made it const
by default and required mutable
to change it.
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda tostd::sort
, then trying to use it again outside ofstd::sort
(or in a second call tostd::sort
) wouldn't show any of the changes made by the calls instd::sort
, right?
– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
add a comment |
up vote
18
down vote
Found this paper by Herb Sutter at open-std.org which discusses this matter.
The odd couple: Capture by value’s injected const and quirky mutable
Consider this strawman example, where the programmer captures a local variable by value and tries to modify the captured value (which is a member variable of the lambda object):
int val = 0;
auto x = [=]( item e ) // look ma, [=] means explicit copy
{ use( e, ++val ); }; // error: count is const, need ‘mutable’
auto y = [val]( item e ) // darnit, I really can’t get more explicit
{ use( e, ++val ); }; // same error: count is const, need ‘mutable’
This feature appears to have been added out of a concern that the user might not realize he got a copy, and in particular that since lambdas are copyable he might be changing a different lambda’s copy.
The above quote and example indicate why the Standards Committee might have made it const
by default and required mutable
to change it.
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda tostd::sort
, then trying to use it again outside ofstd::sort
(or in a second call tostd::sort
) wouldn't show any of the changes made by the calls instd::sort
, right?
– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
add a comment |
up vote
18
down vote
up vote
18
down vote
Found this paper by Herb Sutter at open-std.org which discusses this matter.
The odd couple: Capture by value’s injected const and quirky mutable
Consider this strawman example, where the programmer captures a local variable by value and tries to modify the captured value (which is a member variable of the lambda object):
int val = 0;
auto x = [=]( item e ) // look ma, [=] means explicit copy
{ use( e, ++val ); }; // error: count is const, need ‘mutable’
auto y = [val]( item e ) // darnit, I really can’t get more explicit
{ use( e, ++val ); }; // same error: count is const, need ‘mutable’
This feature appears to have been added out of a concern that the user might not realize he got a copy, and in particular that since lambdas are copyable he might be changing a different lambda’s copy.
The above quote and example indicate why the Standards Committee might have made it const
by default and required mutable
to change it.
Found this paper by Herb Sutter at open-std.org which discusses this matter.
The odd couple: Capture by value’s injected const and quirky mutable
Consider this strawman example, where the programmer captures a local variable by value and tries to modify the captured value (which is a member variable of the lambda object):
int val = 0;
auto x = [=]( item e ) // look ma, [=] means explicit copy
{ use( e, ++val ); }; // error: count is const, need ‘mutable’
auto y = [val]( item e ) // darnit, I really can’t get more explicit
{ use( e, ++val ); }; // same error: count is const, need ‘mutable’
This feature appears to have been added out of a concern that the user might not realize he got a copy, and in particular that since lambdas are copyable he might be changing a different lambda’s copy.
The above quote and example indicate why the Standards Committee might have made it const
by default and required mutable
to change it.
edited 2 days ago
answered 2 days ago
P.W
8,0702439
8,0702439
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda tostd::sort
, then trying to use it again outside ofstd::sort
(or in a second call tostd::sort
) wouldn't show any of the changes made by the calls instd::sort
, right?
– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
add a comment |
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda tostd::sort
, then trying to use it again outside ofstd::sort
(or in a second call tostd::sort
) wouldn't show any of the changes made by the calls instd::sort
, right?
– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
1
1
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda to
std::sort
, then trying to use it again outside of std::sort
(or in a second call to std::sort
) wouldn't show any of the changes made by the calls in std::sort
, right?– ShadowRanger
2 days ago
The "lambdas are copyable" argument seems a strong one. That would mean that passing the lambda to
std::sort
, then trying to use it again outside of std::sort
(or in a second call to std::sort
) wouldn't show any of the changes made by the calls in std::sort
, right?– ShadowRanger
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
@ShadowRanger: That's how I understand it. I did not test it though.
– P.W
2 days ago
add a comment |
up vote
0
down vote
I think, it is simply to avoid confusion when a variable inside a lambda refer not to what was originally captured. Lexically such a variable is as if in scope of its "original". Copying is mainly to allow to extend the lifetime of object. When a capture is not by copy it refers to original and modifications are applied to the original, and there is no confusion because of two different objects (one of which is implicitly introduced), and it is allowed by lambda's const function call operator.
New contributor
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
add a comment |
up vote
0
down vote
I think, it is simply to avoid confusion when a variable inside a lambda refer not to what was originally captured. Lexically such a variable is as if in scope of its "original". Copying is mainly to allow to extend the lifetime of object. When a capture is not by copy it refers to original and modifications are applied to the original, and there is no confusion because of two different objects (one of which is implicitly introduced), and it is allowed by lambda's const function call operator.
New contributor
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
add a comment |
up vote
0
down vote
up vote
0
down vote
I think, it is simply to avoid confusion when a variable inside a lambda refer not to what was originally captured. Lexically such a variable is as if in scope of its "original". Copying is mainly to allow to extend the lifetime of object. When a capture is not by copy it refers to original and modifications are applied to the original, and there is no confusion because of two different objects (one of which is implicitly introduced), and it is allowed by lambda's const function call operator.
New contributor
I think, it is simply to avoid confusion when a variable inside a lambda refer not to what was originally captured. Lexically such a variable is as if in scope of its "original". Copying is mainly to allow to extend the lifetime of object. When a capture is not by copy it refers to original and modifications are applied to the original, and there is no confusion because of two different objects (one of which is implicitly introduced), and it is allowed by lambda's const function call operator.
New contributor
New contributor
answered 2 days ago
guest
342
342
New contributor
New contributor
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
add a comment |
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
but why I cannot edit my posts??
– guest
2 days ago
but why I cannot edit my posts??
– guest
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
You should be able to. Just click the edit link here.
– wizzwizz4
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
"Page Not Found" is the result.
– guest
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
Post a bug report on Meta Stack Overflow. That's strange...
– wizzwizz4
2 days ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53445857%2fwhy-is-a-lambdas-call-operator-implicitly-const%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
9
@Bathsheba from what I understand it's compiler-generated, so no UB there
– Ap31
2 days ago
3
There is an school of thought that all variables should be const by default. Perhaps this kind of thinking had some influence?
– Galik
2 days ago
1
@gurram I think the question should be why not? what could be the reason for making it non-const, thus limiting your lambda for no reason?
– Ap31
2 days ago
2
@gurram Think about capturing a pointer by value, which copies the pointer and not what it points to. If you're able to call non-const functions of the object, then that could modify the object, possibly in ways that are unwanted or leads to UB. If the
operator()
function is marked asconst
then that's not possible.– Some programmer dude
2 days ago
2
Its the wrong way around that we have to declare member functions explicitly as
const
and non-const is the default. Its weird that we are used to redundantly repeat the return type of a function whenauto
return types could be natural. In some sense lambdas give you a glimpse of how c++ could look like if it was reinvented from scratch today.– user463035818
2 days ago