2010-04-16 13 views
6

favor, eche un vistazo a este código:clase derivada como argumento predeterminado g ++

template<class T> 
class A 
{ 
class base 
{ 

}; 

class derived : public A<T>::base 
{ 

}; 

public: 

int f(typename A<T>::base& arg = typename A<T>::derived()) 
{ 
    return 0; 
} 
}; 

int main() 
{ 
A<int> a; 
a.f(); 
return 0; 
} 

compilación genera el siguiente mensaje de error en g ++:

test.cpp: In function 'int main()': 
test.cpp:25: error: default argument for parameter of type 
        'A<int>::base&' has type 'A<int>::derived' 

La idea básica (usando clase derivada como valor por defecto para el argumento de tipo de referencia base) funciona en Visual Studio, pero no en g ++. Tengo que publicar mi código en el servidor de la universidad donde lo compilan con gcc. ¿Que puedo hacer? ¿Hay algo que este olvidando?

+3

No se ha resuelto el error, pero puede escribir 'int f (base & arg = derived())'. – kennytm

Respuesta

7

No se puede crear una referencia (mutable) a un valor r. Trate de usar una constante referencia:

int f(const typename A<T>::base& arg = typename A<T>::derived()) 
//  ^^^^^ 

Por supuesto que no se puede modificar arg con una constante referencia. Si tiene que usar una referencia (mutable), use sobrecarga.

int f(base& arg) { 
    ... 
} 
int f() { 
    derived dummy; 
    return f(dummy); 
} 
+0

+1 por ofrecer sobrecarga como alternativa –

+0

Gracias a todos, esto resolvió mi problema. La versión const fue suficiente, en el contexto real, base es una clase de predicado para comparar cosas, por lo que no es necesario modificarlo. – Vincent

+2

Ha sido desconectado por una extensión de Visual Studio, compila con Warning Level 4 y debería iniciarse en esto. –

4

El problema al que se enfrenta es que no puede usar un argumento temporal como predeterminado para una función que toma una referencia no constante. Los temporales no pueden vincularse a referencias no constantes.

Si no está modificando el objeto internamente, a continuación, puedes cambiar la firma a:

int f(typename A<T>::base const & arg = typename A<T>::derived()) 

Si en realidad se está modificando la pasaron en el argumento, se debe usar alguna otra técnica para permitir argumentos opcionales , el más simple de los cuales sería usar un puntero que se puede predeterminar a NULL.

Cuestiones relacionadas