Tengo una función de plantilla sobrecargada:
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;
}
Si lo llamo así:
auto a = overMax(4, 7.2); // uses first template
auto b = overMax<double>(4, 7.2); // uses second template
todo funciona perfecto, pero
auto c = overMax<int>(4, 7.2); // error
provoca llamadas ambiguas.
¿Por qué es así con int y OK qué otros tipos?
c++
templates
c++17
visual-studio-2019
template-argument-deduction
amplificador
fuente
fuente

int, ¿está especificando eltypename RTo eltypename T1? Como4también es unint, podría ser cualquiera. Condouble,4no coincide directamente con el tipodouble, por lo que se prefiere la segunda sobrecarga.Respuestas:
RTno es deducible, por lo que cuando no se proporciona, solotemplate<typename T1, typename T2> auto overMax(T1 a, T2 b)se puede llamar.Cuando proporciona (parcialmente) un argumento de plantilla, ambos métodos son viables,
pero dependiendo del argumento, uno puede ser un mejor candidato:
por
auto b = overMax<double>(4, 7.2); // uses second templateAmbos
overMax<double, int, double>yoverMax<double, double>son viables.Pero
overMax<double, int, double>es coincidencia exactamientras que
overMax<double, double>se requiereintparadoublela conversión.por
auto c = overMax<int>(4, 7.2); // Ambiguous callAmbos
overMax<int, int, double>yoverMax<int, double>son viables.Pero ninguno de los dos es mejor o más especializado, por lo que la llamada es ambigua.
fuente
overMax<int>(4, 7.2)sería en el primer casoT1=int(proporcionado),T2=double(deducido) y en el segundo casoRT=int(proporcionado),T1=int, T2=double(deducido). La definición de contenido de ambos métodos no se utiliza para seleccionar la sobrecarga.