2010-09-08 15 views
6

Bu örneğin neden derlenmediğini anlamaya çalışıyorum. Anlayışım, statik bir değişken açıkça ayarlanmadığı takdirde varsayılan olarak 0'a ayarlanmasıdır. Dört örnekte, dördü aşağıda beklediğim gibi davranır, ancak yorumda bulunacak olanı derlemez.Şablonlu bir sınıfın statik üyelerini sıfırlama

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

Neden int Bar<2>::iint Foo::i veya static int i aynı şeyi yapmıyor?

Düzenleme: Bar < 2 şablonu <> ekle> ve < 3> bildirimleri Bar unutmuştu. Standart C son Taslağa göre

+3

[Özel şablon sınıfı için statik üye başlatma] 'nın kopyası (http://stackoverflow.com/questions/2342550/static-member-initialization-for-specialized-template-class). –

+0

Bağlantı hatası nedir? – Chubsdad

+0

@Chubsdad: Kuşkusuz, "Bar <2> :: i" tanımına atıfta bulunulmamış. OP'nin kodunda, 'template <> int Bar <2> :: i; 'bir _nondefining_ bildirgesidir (litb'nin ayrıntılı açıklaması için bağlantılı çoğaltmaya bakın). –

cevap

5

Geçerli C++ standardının kuralları uyarınca, template <> int Bar<2>::i; uzmanlığı yalnızca bir bildirimdir ve hiçbir zaman bir tanım değildir. Bir tanım olması için bir başlatıcı belirtmeniz gerekir. Bu tanımını sağlar

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

: Bir şablonun olmayan uzman statik üyesi tanımını:

Bunun dışında

, bir çok yaygın durumda eksik (14.7.3/15 fıkra bakınız) Bar<N>::i N için 2 veya 3'e eşit değil.

1

(hala bağlayıcı hataları alıyorum olsa sorunu çözmez) ++ o

14.7.3/13 bir şablonun bir statik veri üyesi bir açık uzmanlaşma bir olduğunu söylüyor Bildirimin bir başlatıcı içerdiği tanım; aksi halde, bir beyanname.
[Not: Varsayılan başlatma gerektiren bir şablonun bir statik veri üyesi tanımı bir hazırladı-init-listeyi kullanması gerekir:

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

- uç not]

Peki soruyorsunuz mümkündür Derleyiciniz destekliyorsa.

İlgili konular