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;, то программа плохо сформирована.