Сбой вычета аргумента шаблона и несоответствие параметров / параметров функции - PullRequest
0 голосов
/ 27 октября 2018

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

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 ]

0 голосов
/ 28 октября 2018

Это CWG1391 :

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

0 голосов
/ 28 октября 2018

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

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

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

...