This piece of code is accepted by 10.2, but rejected by yesterday's (20210414) snapshot: $ cat test.cpp template<typename = decltype([]{})> void f() {} $ ../GCC-11/bin/g++ -std=c++20 -c test.cpp test.cpp:2:30: error: lambda-expression in template parameter type 2 | template<typename = decltype([]{})> | It's a recent change in behaviour. Possibly caused by r11-8166-ge1666ebd9ad31dbd8b9b933c883bdd882cfd1522. I'm labeling this as rejects-valid because I believe [basic.def.odr]/14 allows such an use of a lambda, but I hardly understand that wording.
Confirmed.
> It's a recent change in behaviour. Possibly caused by > r11-8166-ge1666ebd9ad31dbd8b9b933c883bdd882cfd1522. I can confirm that.
Of course such use of a lambda is quite pointless which in turn makes the P1 classification a bit odd (but given it's a new regression it's technically correct). We'll be happy to demote this to P2 though.
> Of course such use of a lambda is quite pointless Not as pointless as it might appear. This defaulted template parameter enables a form of stateful metaprogramming: #include <type_traits> template<typename, typename = decltype([]{})> class T {}; static_assert(!std::is_same_v<T<int>, T<int>>); // passes with GCC 10 I don’t know if that is valid C++, and would love to know whether or not it is. On the other hand, sometimes it is convenient to use lambdas this way: template<typename TOp = decltype([](double x) { return x * x; })> class my_functor { [[no_unique_address]] TOp const Op = {}; };
Fixed in r11-8199