Как работает вывод аргумента шаблона, когда перегруженная функция используется в качестве аргумента?

Это более сложный вопрос упоминается в Как работает разрешение перегрузки, когда аргумент является перегруженной функцией?

Ниже код компилируется без проблем:

void foo() {}
void foo(int) {}
void foo(double) {}
void foo(int, double) {}

// Uncommenting below line break compilation
//template<class T> void foo(T) {}

template<class X, class Y> void bar(void (*f)(X, Y))
{
f(X(), Y());
}

int main()
{
bar(foo);
}

Это не выглядит сложной задачей для вывода аргумента шаблона — есть только одна функция foo() который принимает два аргумента. Тем не менее, раскомментирование перегрузки шаблона foo() (который все еще имеет только один параметр) прерывает компиляцию без видимой причины. Сбой компиляции как с gcc 5.x / 6.x, так и clang 3.9.

Может ли это быть объяснено правилами разрешения перегрузки / вывода аргументов шаблона или его следует квалифицировать как дефект в этих компиляторах?

21

Решение

Как отмечено в ответе на ваш связанный вопрос:

[temp.deduct.call]/6:когда P тип функции, указатель на тип функции или указатель на тип функции-члена:

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

Так как набор перегрузки содержит шаблон функции, параметр обрабатывается как невнедренный контекст. Это приводит к сбою вывода аргумента шаблона:

[temp.deduct.type]/4: […] Если параметр шаблона используется только в не выводимых
контексты и явно не указаны, вывод аргумента шаблона завершается неудачно.

И этот неудачный вывод дает вам вашу ошибку. Обратите внимание, что если вы явно указываете аргументы, код успешно компилируется:

bar<int,double>(foo);

Живая демо

20

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector