2011-02-05 14 views
7

No es una declaración de clase de plantilla con parámetros implícitos:plantillas con parámetros implícitos, declaración adelantada, C++

list.h

template <typename Item, const bool attribute = true> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    .... 
}; 

He intentado utilizar la declaración hacia adelante fllowing en un fichero de cabecera diferente :

Analysis.h

template <typename T, const bool attribute = true> 
class List; 

Pero G ++ muestra este error:

List.h:28: error: redefinition of default argument for `bool attribute' 
Analysis.h:43: error: original definition appeared here 

Si utilizo la declaración hacia adelante sin parámetros implícitos

template <typename T, const bool attribute> 
class List; 

compilador no acepta esta construcción

Analysis.h

void function (List <Object> *list) 
{ 
} 

y muestra el siguiente error (es decir, no acepta el valor implícito):

Analysis.h:55: error: wrong number of template arguments (1, should be 2) 
Analysis.h:44: error: provided for `template<class T, bool destructable> struct List' 
Analysis.h:55: error: ISO C++ forbids declaration of `list' with no type 

pregunta Actualizado:

me quita el parámetro por defecto de la definición de plantilla:

list.h

template <typename Item, const bool attribute> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    .... 
}; 

La primera el archivo que utiliza la clase Lista tiene una declaración directa con el valor implícito del atributo de parámetro

Analysis1.h

template <typename T, const bool attribute = true> 
class List; //OK 

class Analysis1 
{ 
    void function(List <Object> *list); //OK 
}; 

La segunda clase utilizando Lista de clases con la definición hacia adelante usando el valor implícito

Analysis2.h

template <typename T, const bool attribute = true> // Redefinition of default argument for `bool attribute' 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //OK 
}; 

La segunda clase utilizando la lista de clase sin definición hacia adelante usando el valor implícito

Analysis2.h

template <typename T, const bool attribute> // OK 
class List; 

class Analysis2 
{ 
    void function(List <Object> *list); //Wrong number of template arguments (1, should be 2) 
}; 
+0

bien entiendo su problema. Es porque usted agrega la declaración directa en cada archivo donde * usa * 'Lista'. NO HAGAS ESO. En su lugar, agregue la declaración forward en 'List.h' donde * define * la' Lista' ** y ** '#include" List.h "' en cada archivo donde use 'List'. ¡Avíseme si todavía tiene problemas! – Nawaz

+0

¿cuál es su pregunta después de la actualización? – UmmaGumma

Respuesta

5

Simple.Elimine el valor predeterminado de la definición, ya que ya lo mencionó en la declaración directa.

template <typename Item, const bool attribute = true> //<--- remove this 'true` 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

Comentario:

template <typename Item, const bool attribute> //<--- this is correct! 
class List: public OList <item, attribute> 
{ 
    //.. 
}; 

Demo Online: http://www.ideone.com/oj0jK

+1

Gracias, funciona :-). – Robo

+0

@Robo: si funcionó, entonces "acepta" esta respuesta haciendo clic en la marca de verificación. ¡Hasta ahora no has aceptado ni una sola respuesta! – Nawaz

+0

@Nawaz: Prefiero colocar el valor predeterminado en la declaración en lugar de la declaración directa. Creo que es aún más claro de esta manera. – jopasserat

0

puede definir el parámetro predeterminado en un solo lugar (para una traducción determinada). es más útil hacerlo en la declaración de clase, y una mala idea para definirlo en el forward.

un reenvío no necesita el parámetro predeterminado (solo tendrá que escribirlo en algunos casos).

puede crear otro tipo de plantilla simple que implemente esto junto con un reenvío, si realmente desea un parámetro predeterminado. luego accedes al resultado a través de un typedef. puedes hacer esto usando un reenvío de List.

0

Debe asegurarse de que sólo la primera declaración tiene el valor por defecto del parámetro. Esto se puede lograr definiendo primero un encabezado forward-declaration-only, y luego incluyéndolo desde List.h y Analysis.h. En la definición en List.h, no incluya el valor predeterminado.

0

Debe incluir List.h en cada archivo, donde lo esté utilizando. La declaración es suficiente solo para tipos sin plantilla. Para los tipos de plantilla, debe incluir el archivo de encabezado para cada unidad de compilación.

+0

Pero, ¿cómo evitar la degeneración circular en los archivos de encabezado con este modelo? – Robo

+0

@Robo No digo, que no puede declararlo, digo, que debe incluir el archivo de encabezado. Para resolver dependencias, es probable que deba declarar las clases antes de incluir el encabezado. Pero robar debe incluir encabezado – UmmaGumma

+0

Gracias por su respuesta, actualicé mi pregunta ... – Robo

2

Una posible solución es declarar otro archivo de cabecera, List_fwd.h

template <typename Item, const bool attribute> 
class List; 

Así, tanto en list.h y Analysis.h incluir List_fwd.h al principio. Así se convierte en list.h

#include "List_fwd.h" 

template <typename Item, const bool attribute = true> 
class List: public OList <item, attribute> 
{ 
    public: 
    List() : OList<Item, attribute>() {} 
    ... 
}; 

Y Analysis.h

#include "List_fwd.h" 
Cuestiones relacionadas