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 RT
o eltypename T1
? Como4
también es unint
, podría ser cualquiera. Condouble
,4
no coincide directamente con el tipodouble
, por lo que se prefiere la segunda sobrecarga.Respuestas:
RT
no 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 template
Ambos
overMax<double, int, double>
yoverMax<double, double>
son viables.Pero
overMax<double, int, double>
es coincidencia exactamientras que
overMax<double, double>
se requiereint
paradouble
la conversión.por
auto c = overMax<int>(4, 7.2); // Ambiguous call
Ambos
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.