Inicjalizacja statycznego elementu członkowskiego w szablonie klasy

148

Chciałbym to zrobić:

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

ale nie mogę, ponieważ something_relevantnie jest typu integralnego. Nie zależy od T, ale istniejący kod zależy od tego, czy jest statycznym członkiem S.

Ponieważ S jest szablonem, nie mogę umieścić definicji w skompilowanym pliku. Jak rozwiązać ten problem?

Alexandre C.
źródło
dotyczy również std::stringtypu
Trevor Boyd Smith
Od czasu C ++ 11 słowo kluczowe inline zostało zmienione tak, że zmienne statyczne mogą być inicjowane w momencie deklaracji. Więc deklaracja tego będzie wyglądać następująco: „inline static double something_relevant = 1.5;”
@ user8991265 Wierzę, że zmienne wbudowane są dostępne od C ++ 17, a nie C ++ 11.
zupazt3

Odpowiedzi:

195

Po prostu zdefiniuj to w nagłówku:

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

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

Ponieważ jest częścią szablonu, tak jak w przypadku wszystkich szablonów, kompilator upewni się, że jest zdefiniowany tylko raz.

sbi
źródło
4
@sbi: czy to nie narusza reguły jednej definicji?
Alexandre C.
7
Nie, jeśli mówimy o szablonach. W przeciwnym razie zrobiłyby to również szablony funkcji.
sbi
1
@sbi, @Prasoon: właściwie Prasoon wydaje się być pierwszym. Ale nadal akceptuję sbi z powodu komentarza na temat ODR (który był moim głównym zmartwieniem).
Alexandre C.,
1
@sbi po prostu najedź kursorem na tekst :)
Johannes Schaub - litb
5
@Johannes: Cholera, jestem tu przez rok i nie wiedziałem o tym! Czego jeszcze mi brakuje? (Wciąż pamiętam wstyd, kiedy odkryłem, że dwie liczby, które pojawiają się po kliknięciu liczby głosów, nie są błędem, ale funkcją.) <goes_playing>Wow, kiedy najeżdżam kursorem na Twoje imię, widzę Twojego przedstawiciela! Tego też nie znałam. @Prasoon: Nie, masz rację, iteracyjnie dotarłem do miejsca, w którym jest teraz. (Dlatego też zagłosowałem za twoją odpowiedzią, BTW.)
sbi
31

To zadziała

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;
Prasoon Saurav
źródło
Nie zdefiniowałem zmiennej something_relevant (usunąłem błąd template<typename T> double S<T>::something_relevant=1.5;)rzucania kompilatora, czy możesz mi powiedzieć, jaki jest powód?
goodman