helios,
I badly expressed myself, by "accidental modifications of implicitly captured *this" I meant that the coder may modify
this
for real (implicit capture by reference) while he did not intend to do so, not that the
const
qualifier would cast away.
Compiler works as it should but consider following modified example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
#include <iostream>
struct A
{
void do_it1()
{
std::cout << "do_it()\n";
[=]()
{
this->x = 1;
}();
}
void do_it2()
{
std::cout << "do_it2()\n";
[&]()
{
this->x = 2;
}();
}
int x = 0;
};
int main()
{
A a;
std::cout << a.x << std::endl;
a.do_it1();
std::cout << a.x << std::endl;
a.do_it2();
std::cout << a.x << std::endl;
}
| |
Here in this code sample in both cases x is modified for real!
But a casual coder may believe that
do_it1()
will not modify
this
for real because it was implicitly captured by copy rather than by reference which is wrong regardless of
[=]
capture default.
This behavior has been fixed in C++20, where
do_it1()
will not modify the real
this
Now, what does this have to do with lambda being
const
by default?
I'm not really sure at this point but likely because of consistency with capture by reference version, that is to prevent "self shooting" that was possible with implicit capture of this and forcing the coder to explicitly type
mutable
.
That's silly. It's the programmer's job to understand the copy semantics of the objects he's using. If he doesn't then even forbidding non-const calls may not be enough to prevent foot shootings. |
That's exactly why I think why default is const, if programmer explicitly writes
mutable
then he declares he is probably aware of consequences.