SFINAE и decltype (авто)
Если шаблон функции возвращает decltype(auto)
(или другой спецификатор типа с помощью auto
), но оператор return будет плохо сформирован, получается SFINAE? Является ли оператор return
считаться непосредственным контекстом сигнатуры функции?
Ничто в проекте N3690, похоже, не требует этого. По умолчанию, я думаю, SFINAE не применяется.
Это кажется неудачным, потому что вы можете написать функцию для перехода к другой функции, но вы не можете сделать ее существование условным для делегата, как при написании longhand. Кроме того, проверка существования однонаправленной функции-члена не может быть выполнена без decltype(auto)
, потому что this
не может использоваться в сигнатуре функции. Однако это указывает на фундаментальную проблему, так как decltype(auto)
предоставляет путь к рассмотрению типа класса как завершенного в членной сигнатуре, где это не так.
Было ли написано предложение или была ли формально проанализирована проблема?
Возможность относиться к типу класса как к полному в членной сигнатуре может иметь другие последствия... но это просто корм для другого вопроса.
Ответы
Ответ 1
но оператор return будет плохо сформирован, получается SFINAE?
предложение-n3638 говорит,
SFINAE
Поскольку тип возвращаемого значения выводится путем создания экземпляра шаблона, , если экземпляр некорректно сформирован, это вызывает ошибку, а не сбой замены. Это позволяет автофункции возвращать лямбда, что невозможно с помощью шаблона decltype (return expression).
Надеюсь, это то, что вы ищете.
Ответ 2
Следуя ссылке на Nawaz, на оставшиеся вопросы отвечает N3690 §7.1.6.4/11:
Если тип объекта с неопределенным типом-заполнителем необходим для определения типа выражения, программа плохо сформирована.
Это означает, что даже если SFINAE работал с выводом типа возвращаемого типа, его нельзя было бы использовать для запроса объявления одной функции от другого. Подпись по существу недействительна до тех пор, пока не будет обработан оператор return
, который возникает в закрывающей скобке определения class {}
и после того, как будут обработаны определения предыдущих членов.
В некотором смысле все функции-члены decltype(auto)
являются неполными относительно предыдущих функций в одном классе:
struct s {
void f() { a(); } // error: use of ‘auto s::a()’ before deduction of ‘auto’
auto a() { return 3; }
};
Это жалоба GCC; он исчезает, если объявления участников отменены. Это связано с тем, что определения функций обрабатываются в порядке объявления, когда достигается }
из определения класса. Если инструкция a();
обрабатывается до return 3;
, то программа плохо сформирована.