Автоматический возврат типа шаблона и неоднозначность - PullRequest
20 голосов
/ 15 января 2020

У меня перегружена функция шаблона:

template<typename T1, typename T2>
auto overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

template<typename RT, typename T1, typename T2>
RT overMax(T1 a, T2 b)
{
    std::cout << __FUNCSIG__ << std::endl;

    return b < a ? a : b;
}

Если я назову это так:

auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template

все работает идеально, но

auto c = overMax<int>(4, 7.2); // error

вызывает неоднозначный вызов.

Почему так обстоит дело с int , а с какими другими типами все в порядке?

1 Ответ

25 голосов
/ 15 января 2020

RT не выводится, поэтому, если его не предоставить, можно вызвать только template<typename T1, typename T2> auto overMax(T1 a, T2 b).

Когда вы (частично) предоставляете один аргумент шаблона, оба метода являются жизнеспособными,

но в зависимости от аргумента, лучшим кандидатом может быть:

  • Для auto b = overMax<double>(4, 7.2); // uses second template

    Оба overMax<double, int, double> и overMax<double, double> являются жизнеспособными.
    Но overMax<double, int, double> - точное совпадение
    , тогда как overMax<double, double> требует преобразования int в double.

  • Для auto c = overMax<int>(4, 7.2); // Ambiguous call

    И overMax<int, int, double>, и overMax<int, double> являются жизнеспособными.
    Но ни один из них не является более подходящим или более специализированным, поэтому вызов неоднозначен.

...