Есть ли гарантия порядка подстановки в шаблоне функции после определения типа?

Рассмотрим этот шаблон функции:

template<typename T>
typename soft_error<T>::type foo(T, typename hard_error<T>::type)
{ }

После выведения типа T из типа первого аргумента в вызове foo() компилятор продолжит замену T и создаст экземпляр сигнатуры функции.

Если подстановка для возвращаемого типа выполняется первой, вызывая простой сбой подстановки, компилятор отбрасывает этот шаблон функции при вычислении набора перегрузки и поиске других жизнеспособных перегрузок (SFINAE).

С другой стороны, если замена для второго параметра функции происходит первой, вызывая серьезную ошибку (например, из-за сбоя замены в не немедленном контексте), вся компиляция завершится ошибкой.

ВОПРОС: Есть ли гарантия относительно порядка, в котором будет выполняться подстановка для параметров функции и типов возвращаемых значений?


ПРИМЕЧАНИЕ. Этот пример, кажется, показывает, что на всех основных компиляторах (VC11 тестировался отдельно и давал идентичные результаты) подстановка возвращаемого типа происходит до подстановки типов параметров.


person Andy Prowl    schedule 17.03.2013    source источник
comment
Обратите внимание, что позднее указание типа возвращаемого значения меняет ситуацию.   -  person Nicol Bolas    schedule 17.03.2013
comment
@NicolBolas: Верно, это потому, что подстановка на самом деле должна происходить в лексическом порядке - кстати, Xeo правильно указал, что это не то поведение, которое предписано текущим стандартом, поэтому я исправил свой ответ   -  person Andy Prowl    schedule 17.03.2013


Ответы (1)


[ПРИМЕЧАНИЕ. Изначально это не задумывалось как вопрос с ответом самому себе, но я нашел решение при разработке вопроса]


Есть ли гарантия относительно порядка, в котором будет выполняться подстановка для параметров функции и типов возвращаемых значений?

Не в текущем стандарте.

Однако этот отчет о дефектах (любезно предоставлено Xeo) показывает, что это действительно так. Вот предлагаемая новая формулировка параграфа 14.8.2 / 7 стандарта C ++ 11 (который стал частью n3485 draft):

Подстановка происходит во всех типах и выражениях, которые используются в типе функции и в объявлениях параметров шаблона. Выражения включают не только константные выражения, такие как те, которые появляются в границах массива или в качестве аргументов шаблона, не являющегося типом, но также и общие выражения (т. Е. Неконстантные выражения) внутри sizeof, decltype и других контекстов, которые допускают неконстантные выражения. Подстановка выполняется в лексическом порядке и прекращается при обнаружении условия, которое приводит к сбою дедукции. [...]

Как правильно указал Никол Болас в комментариях к вопросу, лексический порядок означает что конечный тип возвращаемого значения будет заменен после типов параметров, как показано в этой прямой пример.

person Andy Prowl    schedule 17.03.2013
comment
Это действительно хорошо. Спасибо, что поделились этим. +1 к вопросам и ответам обоим. - person Nawaz; 17.03.2013