2010-09-08 23 views
6

Sto cercando di capire perché questo esempio non viene compilato. La mia comprensione è che se una variabile statica non è impostata in modo esplicito, viene automaticamente impostata su 0. Nei cinque esempi seguenti quattro si comportano come mi aspetterei, ma quello che viene commentato non verrà compilato.Inizializzazione di membri statici di una classe basata su modelli

#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; 
} 

perché non int Bar<2>::i fanno la stessa cosa come int Foo::i o static int i?

Modifica: avevo dimenticato di aggiungere il modello <> alle dichiarazioni Bar < 2> e Bar < 3>. (Non risolve il problema, però, ancora ricevendo errori di linker)

+3

Duplicazione di [inizializzazione dei membri statici per classe template specializzata] (http://stackoverflow.com/questions/2342550/static-member-initialization-for-specialized-template-class). –

+0

qual è l'errore di collegamento? – Chubsdad

+0

@Chubsdad: Indubbiamente è "Riferimento non definito a" Barra <2> :: i' "o qualcosa che lo significhi. Nel codice dell'OP, 'template <> int Bar <2> :: i;' è una dichiarazione _nondefining_ (vedere il duplicato collegato per la spiegazione dettagliata di litb). –

risposta

5

Secondo le regole dell'attuale standard C++, la specializzazione template <> int Bar<2>::i; è solo una dichiarazione e mai una definizione. Per diventare una definizione, è necessario specificare un inizializzatore. (Si veda la clausola 14.7.3/15)

Oltre a questo, ti mancava un caso molto comune: la definizione di un membro statico non specializzato di un modello:

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

Ciò fornisce una definizione per Bar<N>::i per N non uguale a 2 o 3.

1

Secondo l'ultima bozza di standard C++ si dice

14.7.3/13 Una specializzazione esplicita di un membro di dati statici di un modello è un definizione se la dichiarazione include un inizializzatore; altrimenti, è una dichiarazione.
[Nota: la definizione di un membro di dati statici di un modello che richiede l'inizializzazione di default deve utilizzare un rinforzato-init-list:

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

- nota end]

Quindi quello che chiedete è possibile , se il tuo compilatore lo supporta.

Problemi correlati