Consider the following code:
#include <type_traits>
int main()
{
auto l = [k = 0]
{
static_assert(std::is_same_v<decltype(k), int>);
};
}
clang++
(10.x and trunk) happily compiles the code above.
g++
(10.x and trunk) fails to compile the code above with the following error:
error: static assertion failed 10 | static_assert(std::is_same_v<decltype(k), int>); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Apparently, g++
believes that decltype(k)
evaluates to const int
.
live example on godbolt.org
Since the type of the data member k
should be deduced from 0
(which is a plain, non-const
, int
), I think that this is a g++
bug. In my mental model, the only thing that is const
is the operator()
of the lambda, but not the synthesized data member k
.
Is my assessment correct?
What does the standard say?
The standard is rather explicit in this case. [expr.prim.lambda.capture]/6:
An init-capture without ellipsis 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, [...]
so your code is (roughly - see the rest of the quote above to see how the two differ) equivalent to the following, which gcc accepts!:
auto k = 0;
auto l = [k]
{
static_assert(std::is_same_v<decltype(k), int>);
};
So who's right? For that we see that the type of the k
, which is int
since auto
deduces to int
for 0
.
Then it is only a matter of looking at [dcl.type.decltype]/1.3 which says:
[...] if
E
[the expression insidedecltype
] is an unparenthesized id-expression [...],decltype(E)
is the type of the entity named byE
.
The type of the entity k
is int
. So gcc is wrong.
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