son - template typename t c++
Plantillas con parámetros implícitos, declaración directa, C++ (5)
Debe asegurarse de que solo la primera declaración tenga el valor predeterminado 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.
Hay una declaración de clase de plantilla con parámetros implícitos:
List.h
template <typename Item, const bool attribute = true>
class List: public OList <item, attribute>
{
public:
List() : OList<Item, attribute> () {}
....
};
Intenté usar la declaración de fllowing forward en un archivo de encabezado diferente:
Análisis.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 forward sin parámetros implícitos
template <typename T, const bool attribute>
class List;
el compilador no acepta esta construcción
Análisis.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 actualizada
Eliminé el parámetro predeterminado de la definición de la plantilla:
List.h
template <typename Item, const bool attribute>
class List: public OList <item, attribute>
{
public:
List() : OList<Item, attribute> () {}
....
};
El primer archivo que utiliza la clase List tiene una declaración de reenvío con un valor implícito del atributo de parámetro
Análisis1.h
template <typename T, const bool attribute = true>
class List; //OK
class Analysis1
{
void function(List <Object> *list); //OK
};
La segunda clase que usa la clase List WITH forward definition 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 utiliza la lista de clase SIN definición de reenvío utilizando 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)
};
Debe incluir List.h
en cada archivo, donde lo esté usando. 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.
Sencillo. 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>
{
//..
};
Escribir:
template <typename Item, const bool attribute> //<--- this is correct!
class List: public OList <item, attribute>
{
//..
};
Demostración en línea: http://www.ideone.com/oj0jK
Una posible solución es declarar otro archivo de encabezado, List_fwd.h
template <typename Item, const bool attribute>
class List;
Entonces en List.h y Analysis.h incluye List_fwd.h al principio. Entonces List.h se convierte
#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"
usted puede definir el parámetro predeterminado en un solo lugar (para una traducción dada). 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).
podría 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.