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

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

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

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

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

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

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


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

Ответ 1

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


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

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

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

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

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