2012-04-18 22 views
10

¿Es O.K.? para definir la función virtual de la plantilla de clase fuera de su cuerpo? La función virtual no puede estar en línea, pero para evitar definiciones múltiples en unidades de compilación, se marcarán como inline (suponiendo que los encabezados de las plantillas se incluirán en varios archivos de origen). Por otro lado, el compilador puede ignorar inline, por lo que parece válido. Por un ejemplo, es el siguiente código correcto:Definiciones de plantilla fuera del cuerpo de clase

template <typename T> 
class C 
{ 
public: 
    virtual void f(T val); 
}; 

template <typename T> 
inline 
void C<T>::f(T val) 
{ 
    //definition 
} 

?

BTW gcc (3.4.2) permite omitir inline antes de la definición de la función f(T val) pero no antes de la función análoga de la clase normal. ¿Es solo el comportamiento de gcc?

+5

Utiliza gcc * 3.4.2 *? – jpalecek

+0

@jpalecek en este ejemplo particular, sí. – doc

+1

@doc - Las funciones virtuales * pueden * declararse 'en línea' (pero eso no es necesario aquí). El compilador simplemente tiene un poco más difícil de averiguar exactamente cuándo las funciones pueden estar en línea. –

Respuesta

10

Sí, está bien, incluso sin inline funciona igual para funciones miembro ordinarias y variables estáticas:

// everything in the header: 
template <class T> 
class A 
{ 
    static int i; 
}; 

template <class T> 
int A<T>::i=0; 

cotización estándar: (3,2/5)

No puede haber mor e que una definición de un tipo de clase (Cláusula 9), tipo de enumeración (7.2), función en línea con vinculación externa (7.1.2), plantilla de clase (Cláusula 14), plantilla de función no estática (14.5.6), estática miembro de datos de una plantilla de clase (14.5.1.3), función miembro de una plantilla de clase (14.5.1.1), o especialización de plantilla para que algunos parámetros de plantilla no se especifican (14.7, 14.5.5) en un programa provisto que cada una de fi nición aparece en una unidad de traducción Erent di ff, y proporcionó las de fi niciones cumplir los siguientes requisitos ...

los requisitos básicamente decir que las dos definiciones tienen que ser idénticos.

No funciona en el caso de clases regulares. Tiene que haber a lo sumo una definición en todo el programa.

+0

¿Por qué alguien votó negativamente esta respuesta? – doc

3

Puede definir las funciones allí, siempre que cualquier código que necesite instanciar la función en cuestión tenga visibilidad de ese código en tiempo de compilación (no de tiempo de enlace).

Es bastante común separar una plantilla en 2 archivos, uno es un encabezado tradicional, y el segundo es la implementación, como con las funciones sin plantilla y su implementación. La única diferencia es que debe #incluir el archivo de implementación de la plantilla y el encabezado cuando desee usarlo.

4

Puede definir métodos de plantilla fuera de la definición class, en el mismo encabezado, sin usar inline y sin recibir múltiples errores de definición.

Esto se debe a que una función de plantilla no genera una definición en sí misma, si no está completamente especializada. Para probar mi punto, lo siguiente:

void C<int>::f(int) 
{ 
} 

dará lugar a un error de enlazador, ya que la función tiene una definición en este caso. (Siempre y cuando incluya este en múltiples unidades de traducción Si lo marca en línea:...

inline void C<int>::f(int) 
{ 
} 

el error ya no se produce

Cuestiones relacionadas