Если я правильно понял этот ответ и ссылался на стандартный раздел [dcl.type.auto.educt -5], код:
decltype(auto) a = e;
всегда эквивалентно
decltype( e ) a = e;
Но теперь проблема возникает, если вместо e
я помещаю лямбда-выражение в decltype(auto)
:
decltype(auto) lambda = [](){};
Это, к моему удивлению, с успехом работает как в gcc, так и clang. Причина шока, который я испытал, лежит в стандарте, в котором говорится, что лямбда не должна встречаться в неоцененном операнде [expr.prim.lambda # 2] (внимание мое):
Лямбда-выражение является prvalue, результат результата которого называется закрывающий объект. Лямбда-выражение не должно появляться в неоценимом операнд, в аргументе шаблона, в объявлении alias, в typedef декларации или в объявлении шаблона функции или функции вне его тела функции и аргументов по умолчанию.
Но, как я уже упоминал, пример будет эквивалентен:
decltype([](){}) lambda = [](){};
Приведенный выше код явно явно будет плохо сформирован. Конечно, можно предположить, что оператор [](){}
внутри decltype
является своеобразной ссылкой, которая на самом деле не является ссылкой, как в случае структурированных привязок, но, возможно, там это специальное правило в стандарте, которое я пропустил, запустив лямбда-инициализацию decltype(auto)
?