2010-07-22 40 views
6

Tengo un problema con la inicialización del miembro 'static const'. En una clase con plantilla, defino un miembro const y lo inicializo fuera de la clase.
Cuando incluyo el archivo .h donde esta clase se implementa en varios archivos .cpp, recibo un error LNK2005 (estoy usando VS2010) que dice que la constante ya está definida.Inicialización del elemento estático estático en la clase de plantilla

// List.hpp 
template <class T> 
class List { 
    static const double TRIM_THRESHOLD; 
}; 

template <class T> 
const double List<T>::TRIM_THRESHOLD = 0.8; 

He intentado poner la inicialización miembro en un archivo .cpp, pero cuando me siento un error de vinculador diciendo que la constante no se define en absoluto. Si la lista no está modelada y pongo la inicialización en un archivo .cpp, todo está bien.
¿Hay alguna solución para esta situación? Ya tengo # ifdef/define cláusulas alrededor del archivo, y definitivamente no es una solución.

+1

Falta el modificador 'const' en la definición. – Ropez

+1

¿Estás seguro de que este es tu código? No deberías obtener ningún error. @Ropez: el 'const' solo importa en la declaración. – GManNickG

+0

Curiosamente, VS2015 no tiene este problema. De alguna manera puede optimizar/descubrir que las definiciones estáticas const son realmente todas las mismas cosas y no marca un error en el enlazador. – Menace

Respuesta

7

Debe definir la constante en un archivo fuente no un encabezado (por lo que solo se define una vez) ya que esta es una plantilla que necesita mantener en el encabezado (y todas las instancias tienen el mismo valor) puede usar clase base común.

class ListBase { 
protected: 
    ListBase() {} // use only as base 
    ~ListBase() { } // prevent deletion from outside 
    static const double TRIM_THRESHOLD;  
}; 

template <class T> 
class List : ListBase { 
}; 

// in source file 
double ListBase::TRIM_THRESHOLD = 0.8; 

Otra opción es tenerlo como una función estática:

static double trim_threashold() { return 0.8; } 

Editar: Si su compilador soporta C++ 11 a hacer su método static un constexpr function para que tiene todas las oportunidades de optimización que tiene el uso del valor directamente.

+0

Creo que su punto es incorrecto. Mira http://stackoverflow.com/questions/1553854/template-static-variable – cybevnm

+1

No creo que esté equivocado, porque se usa la herencia, donde el miembro estático está en el antepasado que no es el que tiene la plantilla. luego, usar la función estática también es válido. – uray

+0

Si necesitamos el mismo valor constante para cada instancia de plantilla (TRIM_THRESHOLD es el mismo para la lista o List ) la solución de Motti es la correcta. Si tenemos que hacer esto solo por el escape de errores del enlazador (definiciones múltiples del mismo simbol), esta solución es exagerada. El lenguaje nos permite definir la variable estática de la clase de plantilla en el encabezado. Si Motti quiso decir el primer caso, me disculpo, porque no entendí su punto. – cybevnm

Cuestiones relacionadas