If I understood correctly this answer and referenced standard section [dcl.type.auto.deduct-5], the code:
decltype(auto) a = e;
is always equivalent to
decltype( e ) a = e;
But now the problem appears if instead of e
I put the lambda expression to decltype(auto)
:
decltype(auto) lambda = [](){};
This compiles, to my surprise, successfully in both gcc and clang. Reason for the shock I've experienced lays in standard which says specifically that lambda should not occur in unevaluated operand [expr.prim.lambda#2] (emphasis mine):
A lambda-expression is a prvalue whose result object is called the closure object. A lambda-expression shall not appear in an unevaluated operand, in a template-argument, in an alias-declaration, in a typedef declaration, or in the declaration of a function or function template outside its function body and default arguments.
But as I mentioned the example would be equivalent to:
decltype([](){}) lambda = [](){};
The above code written explicitly obviously would be ill-formed. Of course we could assume that the statement [](){}
inside decltype
is kind of reference that isn't really a reference like in case of structured bindings, but maybe there is a special rule in standard that I've missed covering lambda initializing decltype(auto)
?