There would indeed exist a huge number of use-cases for allowing lambda
expressions, it would probably extremely extend possible sfinae cases
(to include complete code "sand-boxes"). The reason why they became
excluded was due to exactly this extreme extension of sfinae cases (you
were opening a Pandora box for the compiler) and the fact that it can
lead to problems on other examples as yours, e.g.
template<typename T, typename U>
void g(T, U, decltype([](T x, T y) { return x + y; }) func);
is useless, because every lambda expression generates a unique type, so
something like
g(1, 2, [](int x, int y) { return x + y; });
doesn't actually work, because the type of the lambda used in the
parameter is different from the type of the lambda in the call to g
.
Finally it did also cause name-mangling issues. E.g. when you have
template<typename T>
void f(T, A<sizeof([](T x, T y) { return x + y; })> * = 0);
in one translation unit but
template<typename T>
void f(T, A<sizeof([](T x, T y) { return x - y; })> * = 0);
in another translation unit. Assume now that you instantiate f<int>
from both translation units. These two functions have different
signatures, so they must produce differently-mangled template
instantiations. The only way to keep them separate is to mangle the
body of the lambdas. That, in turn, means that compiler writers have
to come up with name mangling rules for every kind of statement in the
language. While technically possible, this was considered as both a
specification and an implementation burden.
constexpr auto f=[]()constexpr{return 42;};
的调用使您的参数毫无意义。 - Yakk - Adam Nevraumont