2010-03-06 7 views
13

El siguiente código funciona con Visual Studio 2008, pero no con GCC/G ++ 4.3.4 20090804. ¿Qué comportamiento es - de acuerdo con el estándar de C++ - correcta ?GCC/VS2008: Diferente comportamiento de llamada a la función cuando la clase base con plantilla se deriva de la misma

template <int N> 
struct A : A<N-1> {}; 

template <> 
struct A<0> {}; 

struct B : A<1> {}; 

template <int N> 
void Func(const A<N> &a) {} 

int main() 
{ 
    A<1> a; //is derived from A<0> 
    Func(a); //vs2008: ok, g++: ok 
       //Comeau: ok 

    B b;  //is derived from A<1> 
    Func(b); //vs2008: ok, g++: error, no matching function for call to Func(B&) 
       //Comeau: error: no instance of function template "Func" matches the 
       //  argument list. The argument types that you used are: (B). 

    return 0; 
} 

Si Func Sobrecarga() con

void Func(const A<0> &a) { std::cout << '0'; } 
void Func(const A<1> &a) { std::cout << '1'; } 

siempre este último se llama (como se esperaba). Así que también esperaría que la función de plantilla fuera llamada con N = 1 porque A < 1> es base directa de B. ¿Es esta suposición realmente incorrecta?

+5

No se compila con Comeau Online tampoco. ¿Qué esperas que sea N en el segundo caso (dado que b es convertible tanto en A <1> como en A <0>)? – UncleBens

+0

Creo que es solo otra extensión de MSVC++. –

+0

@UncleBens, wow, no he visto que 'B' también hereda' A <0>'!Buen ojo :) –

Respuesta

4

Después de algún excavación a través de N3035, he encontrado esta en la sección 14.9.2.1.4:

si p es una clase y P tiene la forma simple-plantilla-id, entonces la transformada A puede ser una clase del A. deducida derivada Asimismo, si P es un puntero a una clase de la forma simple-plantilla-id, la transformada a puede ser un puntero a una clase derivada apuntado por el A. deducida

Sin embargo, en 14.9.2.1.5, que dice:

Estas alternativas se consideran solo si la deducción de tipo de otro modo fallaría. Si producen más de una posible deducción de A, la deducción de tipo falla.

que es el caso: tanto A<1> y A<0> se consideran clases base para B.

supongo que esto significa un no para Visual Studio (al menos, si el estándar actual dice lo mismo: ejercicio para el lector).

+0

+1 para la excavación :) – neuro

0

en ISO/IEC 14882 es casi la misma (14.8.2.1):

  • Si P es una clase, y P tiene la forma de la plantilla-id, entonces A puede ser una clase derivada de la A. deducida Asimismo, si P es un puntero a una clase de la forma de la plantilla-id, a puede ser un puntero a una clase derivada señaló por el A. deducida

Estos altenatives son c onsidered solo si la deducción del tipo fallaría de lo contrario. Si producen más de uno posible deducido A, la deducción del tipo falla.

Así que estoy de acuerdo con Jan. ¿Hay alguien aquí que no?

+0

¿Cuál podría ser la razón por la que se especificó de esta manera? – user287715

Cuestiones relacionadas