c++ templates overload-resolution template-deduction

c++ - ¿Por qué esta llamada a una plantilla no es ambigua?



templates overload-resolution (2)

Cuando usa cast<int, float> , se consideran ambas plantillas.

template<typename T=int,typename U=float> U cast(T x); template<typename T=int,typename U=float> T cast(U x);

entonces sustituimos

template<typename T=int,typename U=float> float cast(int x); template<typename T=int,typename U=float> int cast(float x);

En este punto, no hay tipos para deducir. Así que vamos a sobrecargar la resolución.

En un caso, podemos tomar un int y convertir a float cuando se llama a cast, y en el otro tomar un int y convertir a int cuando se llama a cast. Tenga en cuenta que no estoy mirando todo en el cuerpo de yeso; El cuerpo no es relevante para la resolución de sobrecargas.

La segunda no conversión (en el punto de llamada) es una mejor coincidencia, por lo que se elige la sobrecarga.

Si hiciste esto:

std::cout << cast<int>(10) << "/n";

las cosas se ponen más interesantes:

template<typename T=int,typename U=?> U cast(T x); template<typename T=int,typename U=?> T cast(U x);

para el primero, no podemos deducir U Para el segundo podemos.

template<typename T=int,typename U=?> U cast(int x); template<typename T=int,typename U=int> int cast(int x);

Así que aquí tenemos una sobrecarga viable, y se utiliza.

Declaro dos plantillas, la primera convierte el argumento x del tipo T al tipo U y la segunda del tipo U al tipo T Si llamo a cast con 10, el compilador no se queja. Creo que ambos cumplen con los requisitos para ser utilizados y, por lo tanto, debería haber ambigüedad, ¿es cierto? Este código imprime 10.

#include <iostream> template<typename T, typename U> U cast(T x) { return static_cast<U>(x); } template<typename T, typename U> T cast(U x) { return static_cast<T>(x); } int main() { std::cout << cast<int,float>(10) << ''/n''; }


La creación de instancias no es ambigua porque el argumento de la función coincide exactamente con el primer parámetro de la plantilla: el literal 10 es un int , que también se especifica explícitamente para el primer tipo de plantilla.

Puede hacer que la creación de instancias sea ambigua cuando el tipo de argumento no coincida con los tipos explícitamente especificados (por lo tanto, es necesaria una conversión), por ejemplo

// error: call of overloaded ''cast<int, float>(unsigned int)'' is ambiguous std::cout << cast<int,float>(10u) << "/n";