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