c++ - installed - instalar clang windows
Diferencias de resoluciĆ³n de llamada de plantilla de GCC y Clang (1)
Dado el siguiente código:
#include <iostream>
struct Alice
{
template <typename A>
void operator|(const A& /*a*/) const
{
std::cout << "operator| member" << std::endl;
}
};
template <typename A>
void operator|(const A& /*a*/, const Alice& /*alice*/)
{
std::cout << "operator| non-member" << std::endl;
}
int main()
{
Alice a;
Alice b;
a | b;
return 0;
}
Compila sin previo aviso con GCC 4.8.1, 4.9 y clang 3.4, pero da resultados diferentes.
$ g++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| non-member
$ clang++ -Wall -Wextra -std=c++11 alice.cpp && ./a.out
operator| member
¿Qué causa esta diferencia? ¿Cómo puedo forzar el mismo comportamiento?
EDITAR: Dato interesante: eliminar el calificador const
de la función miembro hace que gcc prefiera también la función miembro. Sin embargo, no resuelve el problema.
EDITAR: clang ++ prefiere el no miembro en su lugar, si -std=c++11
no está especificado.
EDIT: ICC 14.0 prefiere no miembros, no se emiten advertencias.
Según la resolución de sobrecarga, hay dos funciones viables: la especialización del operator|
global operator|
-template con argumentos deducidos y la especialización de la plantilla de función del operador miembro. Ambos tienen la misma firma: la plantilla de función miembro tiene un parámetro de objeto implícito de tipo Alice const&
(ver §13.3.1 / 4).
Entonces ambas funciones viables (después de la deducción del argumento de la plantilla) tienen la misma firma. Y ninguna de las plantillas de las que se crearon las instancias es más especializada que la otra. Entonces esto es de hecho una ambigüedad y, por lo tanto, mal formado. Sorprendentemente, VC ++ es correcto.
¿Cómo puedo forzar el mismo comportamiento?
Quizás debería eliminar la ambigüedad, Clang, VC ++ y GCC deberían tener el mismo comportamiento.