Seite 1 von 1

templates und static variables - wieso kompiliert das?

Verfasst: 25.08.2011, 18:00
von kaiserludi
Folgender Code

Code: Alles auswählen

template<bool isTrue> struct IsTrue;
template<> struct IsTrue<true>
{
};

struct Test
{
	IsTrue<false> failToCompileIfNotTrue;
};
wirft mir wie erwünscht und erwartet einen Kompilierfehler:
'Test::failToCompileIfNotTrue' uses undefined struct 'IsTrue<isTrue>'
1> with
1> [
1> isTrue=false
1> ]
Mache ich die Variable hingegen static

Code: Alles auswählen

template<bool isTrue> struct IsTrue;
template<> struct IsTrue<true>
{
};

struct Test
{
	static IsTrue<false> failToCompileIfNotTrue;
};
so kompiliert der ansonsten unveränderte Code plötzlich seltsamerweise.

Genauso kompiliert das, wenn es in eine lokale Variable in einer Funktion innerhalb von Test ist.

Kann sich das (bzw. mir den Grund) wer erklären?

Die Frage ist eher interessehalber. Habe das eigentlich Problem jetzt anders gelöst (wozu habe ich schließlich COMPILE_TIME_ASSERT_TRUE ...)

Re: templates und static variables - wieso kompiliert das?

Verfasst: 25.08.2011, 18:35
von Krishty
Das mag kompilieren, wird aber nicht linken. Was du da hinschreibst, ist nämlich bloß eine Deklaration einer externen Variable.

Der Compiler erwartet nun -- wie bei allen externen Variablen -- dass in irgendeinem anderen Modul sowohl IsTrue<false> als auch die Klassenvariable isTrue<false> Test::failsToCompileIfNotTrue definiert sind.

Das geht so mit allen nicht definierten Klassen und statischen nicht-konstanten nicht-integralen Variablen ... weil sie in keiner Instanz der Klasse landen, sondern global einzigartig sind (und von ein paar Compilern auch als globale Variablen behandelt werden), braucht der Compiler sie zum Zeitpunkt der Definition von class Test nicht, um die Auslegung von Instanzen der Klasse zu kennen. Darum kümmert er sich an dieser Stelle auch nicht drum.

Aus demselben Grund musst du Klassenvariablen vom Typ wie z.B. float ja auch einmal in der Klassendefinition deklarieren und in einer anderen Datei definieren. Statische integrale Typen sind die einzige Ausnahme weil C++ scheiße ist bis mein Lieblings-Compiler constexpr kann.

Re: templates und static variables - wieso kompiliert das?

Verfasst: 25.08.2011, 18:45
von kaiserludi
Krishty hat geschrieben:Das mag kompilieren, wird aber nicht linken.
Wenn es denn so wäre, wärs mir recht, aber es linkt auch einwandfrei :(

PS:
*seufz* constexpr könnte ich jetzt auch gerade gut gebrauchen.

Re: templates und static variables - wieso kompiliert das?

Verfasst: 25.08.2011, 21:31
von BeRsErKeR
Wenn du die statische Membervariable nie benutzt gibts keine Probleme beim Linken. Wenn du sie aber nutzt erhälst du bereits einen Fehler beim Compilen. Gleiches gilt auch wenn du sie definierst (was man in der Regel bei statischen Membern tun muss). Krishty hat vollkommen Recht, aber wie gesagt gibts keine Linker-Fehler weil die Membervariable schlicht und ergreifend nie benutzt wird.

Ohne static ist das was anderes, da beim Instanziieren der Test-Klasse die Member-Variable ebenfalls instanziiert wird.

Auch globale Variablen (die prinzipiell fast das gleiche wie statische Membervariablen sind) zeigen das gleiche Verhalten:

Code: Alles auswählen

extern IsTrue<false> failToCompileIfNotTrue;
Geht auch ohne Probleme durch Compiler und Linker. ;)