Эта программа плохо сформирована, несмотря на SFINAE?

template <typename T> void f() {
return 0;  // returning value from function returning `void`
}

int main()
{
// Not instantiating or calling any f<T>()
}

В комментариях к этот ответ, Дэвид утверждает, что шаблон функции, который содержит семантическую ошибку и не был создан, приводит к тому, что программа плохо сформирована:

Независимо от того, используется шаблон или нет, программа плохо формируется даже без инстанцирования, но компилятор не обязан его диагностировать.

И наоборот, я вполне уверен, что SFINAE, а также предотвращает вычитание типа и, следовательно, создание экземпляра шаблона функции в соответствии с [C++11: 14.8.2/8], позволяет программе оставаться правильно сформированной. однако я не могу найти текст в этом стандартном параграфе, который прямо говорит об этом.

Кто прав?


Википедия, которую я не считаю авторитетной по этому вопросу, говорит о несколько ином случае:

[..] SFINAE был представлен избегать создания плохо сформированных программ когда были видны несвязанные объявления шаблона [..]

(акцент мой)

2

Решение

Программа плохо сформирована в соответствии с 14.6 / 8:

Если для определения шаблона не может быть сгенерировано никакой действительной специализации, и этот шаблон не создан, определение шаблона неверно, диагностика не требуется.

То есть, если вы создаете экземпляр шаблона или нет, определение шаблона неверно сформировано, так как нет никакой возможной реализации, которая будет успешной.

Обратите внимание, что это совершенно не связано с SFINAE: Ошибка замены не является ошибкой. замена процесс, и никогда не принимает во внимание содержимое шаблона.

9

Другие решения

Читая более внимательно, этот стандартный отрывок гласит:

Если подстановка приводит к недопустимому типу или выражению, вывод типа завершается неудачей. Недопустимый тип или выражение — это то, что было бы неправильно сформировано, если было бы написано с использованием замещенных аргументов. [..]

return 0 не является выражением, поэтому SFINAE не применяется.

Проход продолжается:

Только недопустимые типы и выражения в непосредственном контексте типа функции и ее типов параметров шаблона могут привести к ошибке вывода.

return 0 не имеет ничего общего с типом функции или типами параметров шаблона, поэтому SFINAE по-прежнему не применяется.

1

По вопросам рекламы [email protected]