Initialisation de membre statique dans un modèle de classe


148

J'aimerais faire ceci:

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

mais je ne peux pas puisque ce something_relevantn'est pas de type intégral. Cela ne dépend pas T, mais le code existant dépend du fait qu'il soit un membre statique de S.

Puisque S est un modèle, je ne peux pas mettre la définition dans un fichier compilé. Comment résoudre ce problème?


s'applique également au std::stringtype
— Trevor Boyd Smith

Depuis C ++ 11, le mot clé inline a changé afin que les variables statiques puissent être initialisées au point de déclaration. Ainsi, la déclaration pour cela ressemblerait à "double statique en ligne something_relevant = 1.5;"

@ user8991265 Je crois que les variables en ligne sont disponibles depuis C ++ 17, pas C ++ 11.
— zupazt3

Réponses:


196

Définissez-le simplement dans l'en-tête:

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

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

Puisqu'il fait partie d'un modèle, comme avec tous les modèles, le compilateur s'assurera qu'il n'est défini qu'une seule fois.


4
@sbi: cela ne viole-t-il pas la règle d'une définition unique?
— Alexandre C.

7
Non, pas si nous parlons de modèles. Sinon, les modèles de fonction le feraient également.
— sbi

1
@sbi, @Prasoon: en fait Prasoon semble être le premier. Mais j'accepte toujours les sbi à cause du commentaire sur l'ODR (qui était ma principale préoccupation).
— Alexandre C.

1
@sbi survole le texte :)
— Johannes Schaub - litb

5
@Johannes: Bon sang, je suis ici depuis un an et je ne le savais pas! Que me manque-t-il d'autre? (Je me souviens encore de la honte quand j'ai découvert que les deux chiffres qui apparaissent lorsque je clique sur le nombre de votes ne sont pas un bug, mais une fonctionnalité.) <goes_playing>Wow, quand je survole votre nom, je vois votre représentant! Je ne connaissais pas celui-là non plus. @Prasoon: Non, vous avez raison, je suis arrivé itérativement là où il en est maintenant. (C'est pourquoi j'ai voté pour votre réponse, BTW.)
— sbi


31

Cela fonctionnera

template <typename T>
 struct S
 {

     static double something_relevant;
 };

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

Je n'ai pas défini la variable something_relevant (j'ai supprimé l' template<typename T> double S<T>::something_relevant=1.5;)erreur de lancement du compilateur, pouvez-vous me dire quelle en est la raison?
— goodman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.