equal - overload c++ operator
Este caso de sobrecarga de funciĆ³n de plantilla elude mi comprensiĆ³n (1)
Una vez que tenemos nuestras funciones candidatas establecidas (ambas bar
), y luego reduciéndolas a las funciones viables (aún las dos bar
) tenemos que determinar la mejor función viable. Si hay más de uno, obtenemos un error de ambigüedad. Los pasos que tomamos para determinar el mejor se presentan en [over.match.best]:
[A] la función viable F1 se define como una función mejor que otra función viable F2 si para todos los argumentos i , ICS i (F1) no es una secuencia de conversión peor que ICS i (F2), y luego
- para algunos argumentos j , ICS j (F1) es una secuencia de conversión mejor que ICS j (F2), o, si no es así,
Ambas funciones toman un argumento de tipo int
, por lo que ambas secuencias de conversión son idénticas. Continuamos.
- el contexto es una inicialización por conversión definida por el usuario [...]
No se aplica.
- el contexto es una función de inicialización por conversión para el enlace directo de referencia (13.3.1.6) de una referencia al tipo de función, [...]
No se aplica.
- F1 no es una especialización de plantilla de función y F2 es una especialización de plantilla de función, o, si no es eso,
Ambas bar<int>
son especializaciones de plantilla de función. Así que pasamos al último punto para determinar la mejor función viable.
- F1 y F2 son especializaciones de plantilla de función, y la plantilla de función para F1 es más especializada que la plantilla para F2 de acuerdo con las reglas de ordenamiento parcial descritas en 14.5.6.2.
Las reglas parciales de pedido básicamente se reducen a nosotros sintetizando nuevos tipos únicos para los argumentos de ambas sobrecargas de bar
y realizando deducción de plantilla en la otra sobrecarga.
Considere la sobrecarga "b" primero. Sintetice un tipo typename identity<Unique1>::type
e intente realizar una deducción de plantilla en contra de T
Eso tiene éxito El elenco más simple de la deducción de la plantilla existe.
Luego, considere la sobrecarga "a". Sintetice un tipo Unique2
e intente realizar una deducción de plantilla contra typename identity<T>::type
. ¡Esto falla ! Este es un contexto no deducido, ninguna deducción puede tener éxito.
Como la deducción del tipo de plantilla solo tiene éxito en una sola dirección, la bar(typename identity<T>::type)
la bar(typename identity<T>::type)
se considera más especializada y se elige como el mejor candidato viable.
bogdan presenta otro caso interesante para mirar pedidos parciales. Considere en cambio comparar:
template <typename T> void bar(T, T); // "c"
template <typename T> void bar(T, typename identity<T>::type ); // "d"
bar(5,5);
bar<int>(5, 5);
Una vez más, ambos candidatos son viables (esta vez, incluso sin especificar explícitamente T
) por lo que observamos la regla de ordenamiento parcial.
Para la sobrecarga "c", sintetizamos argumentos de tipo UniqueC, UniqueC
e intentamos realizar deducción contra T, typename identity<T>::type
. Esto tiene éxito (con T == UniqueC
). Entonces "c" es al menos tan especializado como "d".
Para la sobrecarga "d", sintetizamos argumentos de tipo UniqueD, typename identity<UniqueD>::type
e intentamos realizar deducción contra T, T
¡Esto falla! ¡Los argumentos son de diferentes tipos! Entonces "d" no es tan especializado como "c".
Por lo tanto, se llama a la sobrecarga "c".
#include <iostream>
template<typename T>
struct identity
{
typedef T type;
};
template<typename T> void bar(T) { std::cout << "a" << std::endl; }
template<typename T> void bar(typename identity<T>::type) { std::cout << "b" << std::endl; }
int main ()
{
bar(5); // prints "a" because of template deduction rules
bar<int>(5); // prints "b" because of ...?
return EXIT_SUCCESS;
}
Esperaba que bar<int>(5)
resultara en una ambigüedad, como mínimo. ¿Qué regla loca sobre la resolución de sobrecarga de la función de plantilla está involucrada aquí?