Lambda expressions are not allowed in unevaluated contexts (e.g. in decltype) and could not be constant expressions until recently. Therefore there was no way to use them in template arguments.
In C++17 however constant expression lambdas will be possible. This still does not allow using them in template arguments in general.
However specifically for non-type template arguments constant expression lambda expressions could be used in an evaluated context, for example:
template<int N> struct S { constexpr static int value = N; };
int main() {
int N = S<[]()constexpr{return 42;}()>::value;
}
That still doesn't work though, because lambda expressions are explicitly disallowed in template arguments whether type or non-type.
My question is the reasoning behind not allowing the construct above. I can understand that types of lambdas in function signatures might be problematic, but here the closure type itself is irrelevant, only the (compile-time constant) return value is used.
I suspect that the reason is that all statements in the lambda body would become part of the template argument expression and consequently SFINAE would need to be applied if any statement in the body is ill-formed during substitution. Probably that would require significant work from compiler developers.
But that is actually my motivation. If it was possible to use the construct above then SFINAE could be used not only with constant expressions, but also other statements valid in constexpr functions (e.g. literal type declarations).
Besides impact on compiler writers, is there any problem this would cause, e.g. ambiguities, contradictions or complications in the standard?
constexpr auto f=[]()constexpr{return 42;};
on previous line then callf()
makes your argument not make sense. – Yakk - Adam Nevraumont