Since every lambda function in C++ has its own type and the type of lambda function can be used as default value of a template argument, it is interesting to know at which moment that type is substituted in the template. Consider a C++20 program example:
#include <concepts>
template<typename T = decltype([]{})>
using X = T;
template<typename T = X<>>
auto foo() { return T{}; }
int main() {
using T1 = decltype(foo());
using T2 = decltype(foo());
static_assert(!std::same_as<T1, T2>);
}
Here the default type of template argument in the definition of type alias X is the type of lambda function decltype([]{}). And the template function invocation foo() returns a value of that type.
If the substitution of new lambda type takes place every time foo() is present in the program, then the types T1 and T2 must be distinct, as the program verifies in static_assert. And this check passes only in GCC.
In Clang and MSVC the types T1 and T2 are the same, meaning that the substitution of the default type takes place not every time (but rather once during the template declaration). Demo: https://gcc.godbolt.org/z/dzYjf9r3q
Which compiler is right here according to the standard?