2010-03-08 18 views
7

¿Es aconsejable incluir guardias en las clases de plantillas?Clases de plantillas e incluir protecciones en C++

¿No se supone que las clases de plantillas deben repararse cada vez que las referencia con una implementación diferente?

Nota En Visual C++ 2008 me sale ningún error que combinan los dos ...

Respuesta

8

Las plantillas se supone que las definiciones que ser analizado una vez (y cosas como dos fases de búsqueda de nombres están aquí para que la mayor cantidad posible de errores pueden ser dado inmediatamente sin tener una instanciación). Las instancias se hacen usando la estructura de datos interna construida en ese momento.

Las definiciones de las plantillas son usualmente (es decir, si no está usando export o haciendo algo especial) en archivos de encabezado que deberían tener su protector de inclusión. Agregar uno para la definición de la plantilla es inútil pero no dañino.

+5

Agregar incluir guardias siempre, acostumbrarse, ya que es una BUENA práctica. – Poni

+1

Si haces algún desarrollo en win32, incluye '#pragma una vez' siempre que uses incluir guardias. – KitsuneYMG

+0

+1 para indicar que las instancias se hacen usando la estructura de datos interna construida en el momento del primer barrido – Otuken

12

Necesita incluir protecciones. Considere este código:

// this is t.h 
template <typename T> 
void f(T t) { 
} 

// this is t.cpp 
#include "t.h" 
#include "t.h" 

int main() { 
    f(1); 
} 

Esto da el error:

t.h:2: error: redefinition of 'template<class T> void f(T)' 
t.h:2: error: 'template<class T> void f(T)' previously declared here 

Además, las cabeceras que contienen plantillas rutinariamente también contienen código no plantilla.

+2

Estrictamente eso es una función de plantilla en lugar de una clase de plantilla, pero el principio es el mismo: se obtiene un error de definición múltiple si se declara el misma clase dos veces, plantilla o no. –

+0

Vea mi respuesta aquí - http://stackoverflow.com/questions/22595015/c-class-template-undefined-reference-to-function/26816994#26816994 – v010dya

2

Respuesta breve: Cada unidad que planee incluir más de una vez con cualquier definición debe tener una protección de encabezado. Eso es con o sin plantillas.

2

Para responder a su primera pregunta: Sí, es sabio y obligatorio incluir guardias en las clases de plantilla. O más estrictamente rodeando todo el contenido de cada archivo de encabezado.

Esta es la forma de obedecer la regla de una sola definición cuando tiene cosas en los archivos de encabezado, por lo que se comparte y sigue siendo seguro. Puede haber otros archivos de encabezado que incluyen el suyo. Cuando el compilador compila un archivo de módulo, puede ver un #include del archivo de encabezado muchas veces, pero los guardias se activan en el segundo y posteriores para asegurarse de que el compilador solo ve el contenido una vez.

No importa que el compilador repase cualquier cosa; ese es su trabajo. Solo tiene que proporcionar el contenido una vez y luego el compilador lo ha visto y puede consultarlo tantas veces como lo necesite.

Cuestiones relacionadas