This is rejected by g++ (4.9.3 and 5.2.0), but is accepted by clang 3.5.0:
int main() {
const int ci = 0;
auto lambda = [ &cap = ci ]() { };
}
g++ gives error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers
. It appears that g++ refuses to allow non-const references to be captured, except of course using plain old C++11 capture [&ci]
. That seems a very strange constraint, perhaps a bug in g++?
Your code is valid. §5.1.2/11 goes
An init-capture behaves as if it declares and explicitly captures a variable of the form
“auto
init-capture;
” whose declarative region is the lambda-expression’s compound-statement […]
Now, clearly, declaring
auto &cap = ci;
and capturing cap
is fine. That is,
int main() {
const int ci = 0;
auto &cap = ci;
auto lambda = [&cap]() { };
}
compiles with GCC. Apart from the declarative region and lifetime of cap
, there is no difference between this snippet and yours, thus GCC is incorrect.
This bug has already been reported as #66735, with a similar example:
int x = 0;
auto l = [&rx = static_cast<const int&>(x)] {};
This looks similar to gcc bug: [C++14] lambda init-capture fails for const references which says:
This code fails to compile:
int main() { int x = 0; auto l = [&rx = static_cast<const int&>(x)]() {}; }
The error message is:
test.cpp:3:14: error: binding 'const int' to reference of type 'int&' discards qualifiers
auto l = [&rx = static_cast<const int&>(x)]() {
But according to [expr.prim.lambda]/11 rx should be captured as auto &rx = static_cast(x), that is as const int&.
the bug report references [expr.prim.lambda]/11 which says:
An init-capture behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;” whose declarative region is the lambda-expression’s compound-statement, except that[...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With