Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`decltype` of generalized lambda capture inside body of a lambda - gcc vs clang

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?

like image 290
Vittorio Romeo Avatar asked Jul 18 '20 01:07

Vittorio Romeo


1 Answers

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 inside decltype] is an unparenthesized id-expression [...], decltype(E) is the type of the entity named by E.

The type of the entity k is int. So gcc is wrong.

like image 147
Rakete1111 Avatar answered Oct 21 '22 05:10

Rakete1111