Inicialización de miembro estático en una plantilla de clase

148

Me gustaría hacer esto:

template <typename T>
struct S
{
    ...
    static double something_relevant = 1.5;
};

pero no puedo ya something_relevantque no es de tipo integral. No depende de T, pero el código existente depende de que sea un miembro estático S.

Como S es plantilla, no puedo poner la definición dentro de un archivo compilado. ¿Cómo resuelvo este problema?

Alexandre C.
fuente
también se aplica al std::stringtipo
Trevor Boyd Smith el
Desde c ++ 11, la palabra clave en línea ha cambiado para que las variables estáticas se puedan inicializar en el punto de declaración. Entonces, la declaración para esto se vería como "inline static double something_relevant = 1.5;"
@ user8991265 Creo que las variables en línea están disponibles desde C ++ 17, no C ++ 11.
zupazt3

Respuestas:

196

Solo defínalo en el encabezado:

template <typename T>
struct S
{
    static double something_relevant;
};

template <typename T>
double S<T>::something_relevant = 1.5;

Como forma parte de una plantilla, como con todas las plantillas, el compilador se asegurará de que solo se defina una vez.

sbi
fuente
44
@sbi: ¿no viola la regla de una definición?
Alexandre C.
77
No, no si estamos hablando de plantillas. De lo contrario, las plantillas de funciones también lo harían.
sbi
1
@sbi, @Prasoon: en realidad, Prasoon parece ser el primero. Pero todavía acepto los sbi por el comentario sobre la ODR (que era mi principal preocupación).
Alexandre C.
1
@sbi solo pasa el cursor sobre el texto :)
Johannes Schaub - litb
55
@Johannes: ¡Maldición, estoy aquí por un año y no lo sabía! ¿Qué más me estoy perdiendo? (Todavía recuerdo la vergüenza cuando descubrí que los dos números que aparecen cuando hago clic en el número de votos no son un error, sino una característica). ¡ <goes_playing>Wow, cuando paso el mouse sobre tu nombre, veo tu representante! Yo tampoco lo sabía. @Prasoon: No, tienes razón, llegué iterativamente a donde está ahora. (Es por eso que hasta-votado en su respuesta, por cierto.)
OSE
31

Esto funcionará

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;
Prasoon Saurav
fuente
No template<typename T> double S<T>::something_relevant=1.5;)definí la variable something_relevant ( eliminé el error de lanzamiento del compilador. ¿Puede decirme cuál es la razón?
goodman