Позволяет ли C ++ 20 не захватывать лямбду, распадающуюся на указатель функции, для передачи непосредственно в качестве нетипового параметра шаблона?
Да.
Действительно, вы можете go сделать еще один шаг - вам даже не нужно преобразовывать лямбду в указатель на функцию. Вы можете просто предоставить лямбду. Это действительно C ++ 20:
using Y = S<[](int x) -> void { std::cout << x << " hello\n"; }>;
Правило, которое мы имеем в C ++ 20, заключается в том, что лямбды теперь разрешены в неоцененных контекстах ( P0315 ). Среди многих других изменений формулировок в этой статье нарушено правило, запрещающее использование лямбда-выражений в аргументах шаблона ( C ++ 17 [expr.prim.lambda] / 2 ):
A лямбда-выражение не должно появляться в неоцененном операнде, в аргументе шаблона , в объявлении псевдонима , в объявлении typedef или в объявлении функции или шаблона функции вне тела функции и аргументов по умолчанию.
Это предложение больше не существует в C ++ 20.
Снятие этого ограничения позволяет использовать лямбду в качестве аргумента шаблона, а преобразование из лямбды без захвата в указатель на функцию уже было constexpr в C ++ 17. Clang просто не реализует эту функцию (using T = decltype([]{});
компилируется на g cc, еще не на Clang). Я бы еще не назвал эту ошибку лягушкой, это всего лишь функция лягушки, которая еще не реализована (лямбда-выражения в неоцененных контекстах еще не перечислены как реализованные на странице поддержки компилятора cppreference ).
C ++ 20 нетипизированных параметров шаблона ( P1907 ) позволяет даже отбрасывать +
, потому что лямбды без захвата считаются структурными типами ( [temp.param] / 7 ) просто из-за отсутствия элементов данных.