В параграфе 14.8.2/8 Стандарта С++ 11 указаны условия, при которых отказ замены должен или не должен приводить к "жесткой" ошибке компиляции (что приводит к сбою компиляции) или "мягкой" ошибке что просто заставит компилятор отбросить шаблон из набора кандидатов для разрешения перегрузки (без сбоя компиляции и включения известной идиомы SFINAE):
Если подстановка приводит к недопустимому типу или выражению, тип дедукции не выполняется. Недопустимый тип или выражение это тот, который был бы плохо сформирован, если он был написан с использованием замещенных аргументов. [Примечание: проверка доступа выполняется как часть процесса замещения. -end note] Только недопустимые типы и выражения в непосредственном контексте тип функции и ее типы параметров шаблона могут привести к отказу от вычета. [...]
Слова "непосредственный контекст" появляются только 8 раз во всем стандарте С++ 11, и каждый раз, когда за ними следует (или происходит как часть) экземпляр следующего (ненормативного) текста:
[Примечание: оценка замещенных типов и выражений может привести к побочным эффектам, таким как создание шаблона класса специализации и/или функции шаблонов, генерация неявно определенных функций и т.д. Такие побочные эффекты не находятся в "непосредственном контексте" и могут привести к плохому формированию программы. примечание]
Примечание дает (не очень щедрый) намек на то, что подразумевается под непосредственным контекстом, но по крайней мере для меня этого часто недостаточно, чтобы решить, является ли подстановка или не должна вызывать "жесткую" ошибку компиляции.
Вопрос:
Не могли бы вы предоставить объяснение, процедуру принятия решений и/или некоторые конкретные примеры, чтобы помочь выяснить, в каких случаях ошибка замещения выполняется и не встречается в "непосредственном контексте" типа функции и ее типов параметров шаблона?