2010-09-08 14 views
6

Ich versuche herauszufinden, warum dieses Beispiel nicht kompiliert. Mein Verständnis ist, dass, wenn eine statische Variable nicht explizit festgelegt ist, sie standardmäßig auf 0 gesetzt wird. In den folgenden fünf Beispielen verhalten sich vier von ihnen wie erwartet, aber die auskommentierte wird nicht kompiliert.Initialisierung statischer Member einer Vorlagenklasse

#include <iostream> 
class Foo 
{ 
public: 
    static int i; 
    static int j; 
}; 
template <int n> 
class Bar 
{ 
public: 
    Bar(int) { } 
    static int i; 
}; 

static int i; 
int Foo::i; 
int Foo::j = 1; 
template <> int Bar<2>::i; 
template <> int Bar<3>::i = 3; 

int main(int argc, char** argv) 
{ 
    std::cout << "i   " << i << std::endl; 
    std::cout << "Foo::i " << Foo::i << std::endl; 
    std::cout << "Foo::j " << Foo::j << std::endl; 
    //std::cout << "Bar<2>::i " << Bar<2>::i << std::endl; // Doesn't compile? 
    std::cout << "Bar<3>::i " << Bar<3>::i << std::endl; 
    return 0; 
} 

Warum int Bar<2>::i nicht das gleiche tun wie int Foo::i oder static int i?

Edit: Ich hatte vergessen, Vorlage <> zu den Bar < 2> und Bar < 3> Deklarationen hinzuzufügen. (Löst nicht das Problem, aber immer noch Linker Fehler bekommen)

+3

Duplikat von [statische Elementinitialisierung für spezialisierte Template-Klasse] (http://stackoverflow.com/questions/2342550/static-member-initialization-for-specialized-template-class). –

+0

Was ist der Verknüpfungsfehler? – Chubsdad

+0

@Chubsdad: Zweifellos ist es "Undefinierter Verweis auf' Bar <2> :: i' "oder etwas, das bedeutet. Im OP-Code ist 'template <> int Bar <2> :: i;' eine _novefining_deklaration (siehe das verknüpfte Duplikat für die detaillierte Erklärung von litb). –

Antwort

5

Unter den Regeln des aktuellen C++ - Standards ist die Spezialisierung template <> int Bar<2>::i; nur eine Deklaration und niemals eine Definition. Um eine Definition zu werden, müssen Sie einen Initialisierer angeben. (Siehe Abschnitt 14.7.3/15)

Abgesehen davon, dass Sie waren ein sehr häufiger Fall fehlen: die Definition eines nicht spezialisierten statisches Element einer Vorlage:

template <int n> int Bar<n>::i; 

Diese Definition sieht Bar<N>::i für N ungleich 2 oder 3.

1

Nach dem neuesten Entwurf von Standard C++ sagt es

14.7.3/13 Eine explizite Spezialisierung eines statischen Datenelementes einer Vorlage a Definition, wenn die Deklaration einen Initialisierer enthält; Ansonsten ist es eine Deklaration.
[Anmerkung: Die Definition eines statischen Datenelement einer Vorlage, die Standard-Initialisierung erfordert einen verspannten-init-Liste verwenden müssen:

template<> X Q<int>::x;  //declaration 
template<> X Q<int>::x(); // error: declares a function 
template<> X Q<int>::x { }; // definition 

- Endnote]

Also, was Sie fragen, ist möglich , wenn Ihr Compiler es unterstützt.

Verwandte Themen