Statische Elementinitialisierung in einer Klassenvorlage

148

Ich würde das gerne machen:

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

aber ich kann nicht, da something_relevantes nicht vom integralen Typ ist. Es hängt nicht davon ab T, aber vorhandener Code hängt davon ab, dass er ein statisches Mitglied von ist S.

Da S eine Vorlage ist, kann ich die Definition nicht in eine kompilierte Datei einfügen. Wie löse ich dieses Problem?

Alexandre C.
quelle
gilt auch für std::stringTyp
Trevor Boyd Smith
Seit c ++ 11 hat sich das Schlüsselwort inline geändert, sodass statische Variablen zum Zeitpunkt der Deklaration initialisiert werden können. Die Deklaration hierfür würde also wie folgt aussehen: "Inline Static Double Something_relevant = 1.5;"
@ user8991265 Ich glaube, Inline-Variablen sind seit C ++ 17 verfügbar, nicht C ++ 11.
zupazt3

Antworten:

195

Definieren Sie es einfach in der Kopfzeile:

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

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

Da es wie bei allen Vorlagen Teil einer Vorlage ist, stellt der Compiler sicher, dass es nur einmal definiert ist.

sbi
quelle
4
@sbi: Verstößt es nicht gegen die One-Definition-Regel?
Alexandre C.
7
Nein, nicht wenn es sich um Vorlagen handelt. Andernfalls würden dies auch Funktionsvorlagen tun.
sbi
1
@sbi, @Prasoon: Eigentlich scheint Prasoon der erste zu sein. Aber ich akzeptiere immer noch sbi wegen des Kommentars über die ODR (was mein Hauptanliegen war).
Alexandre C.
1
@sbi schwebe einfach über dem Text :)
Johannes Schaub - litb
5
@Johannes: Verdammt, ich bin seit einem Jahr hier und das wusste ich nicht! Was fehlt mir noch? (Ich erinnere mich noch an die Schande, als ich entdeckte, dass die beiden Zahlen, die beim Klicken auf die Anzahl der Stimmen angezeigt werden, kein Fehler, sondern eine Funktion sind.) <goes_playing>Wow, wenn ich über Ihren Namen schwebe, sehe ich Ihren Vertreter! Das wusste ich auch nicht. @Prasoon: Nein, du hast recht, ich bin iterativ dort angekommen, wo es jetzt ist. (Deshalb habe ich Ihre Antwort
hochgestimmt, übrigens
36

Seit C ++ 17 können Sie das statische Element als deklarieren inline, wodurch die Variable in der Klassendefinition definiert wird:

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

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

xaxxon
quelle
1
Dies ist eine ausgezeichnete Antwort. Kurz und präzise. Weitere Informationen finden Sie auch unter en.cppreference.com/w/cpp/language/static#Static_data_members .
Andreee
31

Das wird funktionieren

template <typename T>
 struct S
 {

     static double something_relevant;
 };

 template<typename T>
 double S<T>::something_relevant=1.5;
Prasoon Saurav
quelle
Ich habe die Variable " template<typename T> double S<T>::something_relevant=1.5;)Something_relevant" nicht definiert (ich habe den Fehler beim Auslösen des Compilers entfernt. Können Sie mir bitte sagen, was der Grund ist?
Goodman