Сбой вычета аргумента шаблона и несоответствие параметров и параметров функции

Рассмотрим следующую программу:

template <class T> struct A { using X = typename T::X; };
template <class T, typename A<T>::X* = nullptr> void f(T, int);
void f(...);
template <class T> void g(T, int, typename A<T>::X* = nullptr); // #
void g(...);

int main() {
  // f(0, nullptr); // error
  g(0, nullptr); // ok       
}

g(0, nullptr) компилирует пока f(0, nullptr) нет (проверено под GCC багажник и Clang багажник на Godbolt). Кажется, что во время процесса вывода аргумента шаблона #компилятор не инстанцирует A<int> когда он находит аргумент nullptr не соответствует параметру int, Где стандарт определяет это поведение?

2 ответа

Это CWG1391:

Если вывод выполняется успешно для всех параметров, которые содержат параметры шаблона, которые участвуют в выводе аргументов шаблона, и все аргументы шаблона явно указываются, выводятся или получаются из аргументов шаблона по умолчанию, оставшиеся параметры затем сравниваются с соответствующими аргументами. Для каждого оставшегося параметра P с типом, который не зависел перед заменой каких-либо явно заданных аргументов шаблона, если соответствующий аргумент A не может быть неявно преобразовано в P, вычет не удается.

Возможно, что вас укусила DR # 1844. В [temp.deduct]/8 говорится:

Если подстановка приводит к недопустимому типу или выражению, вывод типа завершается неудачей. Недопустимый тип или выражение - это тип, который был бы неправильно сформирован, с необходимостью диагностики, если он записан с использованием замещенных аргументов. [Примечание: если диагностика не требуется, программа все еще не работает. Проверка доступа выполняется как часть процесса замены. - примечание конца] Только недопустимые типы и выражения в непосредственном контексте типа функции, ее типов параметров шаблона и его явного спецификатора могут привести к ошибке вывода. [Примечание: замена на типы и выражения может привести к таким эффектам, как создание экземпляров специализаций шаблонов классов и / или специализаций шаблонов функций, генерация неявно определенных функций и т. Д. Такие эффекты находятся не в "непосредственном контексте" и могут В результате программа будет плохо сформирована. - конец примечания]

Проблема здесь в том, что "непосредственный контекст" на самом деле не имеет определения, что приводит к расхождению между компиляторами.

Другие вопросы по тегам