Inicialização de membro estático em um modelo de classe

148

Eu gostaria de fazer isso:

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

mas não posso, pois something_relevantnão é do tipo integral. Não depende T, mas o código existente depende de ser um membro estático S.

Como S é modelo, não posso colocar a definição em um arquivo compilado. Como eu resolvo este problema ?

Alexandre C.
fonte
também se aplica ao std::stringtipo #
Trevor Boyd Smith
Desde o c ++ 11, a palavra-chave inline mudou para que variáveis ​​estáticas possam ser inicializadas no ponto da declaração. Portanto, a declaração para isso seria "inline static double something_relevant = 1.5;"
@ user8991265 Acredito que variáveis ​​em linha estejam disponíveis desde C ++ 17, não C ++ 11.
zupazt3 20/04

Respostas:

195

Basta defini-lo no cabeçalho:

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

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

Como faz parte de um modelo, como em todos os modelos, o compilador garantirá que seja definido apenas uma vez.

sbi
fonte
4
@sbi: não viola a regra de uma definição?
Alexandre C.
7
Não, não se estamos falando de modelos. Caso contrário, os modelos de função também o fariam.
sbi 12/07/10
1
@sbi, @Prasoon: na verdade, Prasoon parece ser o primeiro. Mas ainda aceito os sbi por causa do comentário sobre o ODR (que era minha principal preocupação).
Alexandre C.
1
@sbi Passe o mouse sobre o texto :)
Johannes Schaub - litb
5
@ Johannes: Droga, estou aqui há um ano e não sabia disso! O que mais estou perdendo? (Ainda me lembro da vergonha quando descobri que os dois números que aparecem quando clico no número de votos não são um bug, mas um recurso.) <goes_playing>Uau, quando passo o mouse sobre seu nome, vejo seu representante! Também não conhecia esse. @ Pasoon: Não, você está certo, cheguei iterativamente a onde está agora. (É por isso que eu up-votado a sua resposta, BTW.)
SBI
36

Desde o C ++ 17, agora você pode declarar o membro estático inline, o que definirá a variável na definição de classe:

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

live: https://godbolt.org/g/bgSw1u

xaxxon
fonte
1
Esta é uma excelente resposta. Curto e preciso. Consulte também en.cppreference.com/w/cpp/language/static#Static_data_members para obter mais informações.
andreee
31

Isso vai funcionar

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;
Prasoon Saurav
fonte
Eu não defini a variável something_relevant (removi o template<typename T> double S<T>::something_relevant=1.5;)erro de execução do compilador. Você pode me dizer qual é o motivo?
goodman