2010-02-26 156 views
13
class A 
{ 
}; 

template <typename A, int S> 
class B 
{ 
public: 
     static int a[S]; 

     B() 
     { 
       a[0] = 0; 
     } 
}; 

template<> int B<A, 1>::a[1]; 

int main() 
{ 
     B<A, 1> t; 
     t; 
} 

它編譯GCC 4.1之下,但並不鏈接:靜態成員初始化專門的模板類

static.cpp:(.text._ZN1BI1ALi1EEC1Ev[B<A, 1>::B()]+0x5): undefined reference to `B<A, 1>::a' 

我寧願保持初始化的專業,如果有可能,因爲數組中存放了一些具體的數據到類型。

+1

不會B :: a只有1個元素?所以通過引用B :: a [1],你不是索引超出數組的邊界嗎? – Dathan 2010-02-26 15:18:36

+0

我沒有看到'typename A'在那裏做*任何*。 – 2010-02-26 15:27:26

回答

1

您需要實際值分配給它。

template<> int B<A, 1>::a[1] = {0}; 
+1

它不應該是模板<> int B :: a = {0}? – Dathan 2010-02-26 15:19:04

+0

@Dathan:爲什麼?你的代碼是'error:衝突聲明'int B :: a''。 – kennytm 2010-02-26 15:21:11

+1

@Dathan,該聲明將專門化一個整數成員,而不是一個數組。 – 2010-02-26 15:37:14

0

它不會鏈接,因爲您沒有爲靜態成員定義值。

template<> int B<A, 1>::a[] = { 0 }; 

編輯:

順便說一句:我總是喜歡使用升壓::數組而不是本機C-類型:

class A { }; 

template <typename A, std::size_t S> 
class B 
{ 
public: 
    static boost::array<int, S> a; 

    B() { a[0] = 0; } 
}; 

template<> boost::array<int, 1> B<A, 1>::a = { }; 

int main() 
{ 
    B<A, 1> t; 
    cout << t.a[0] << endl; 
} 
31

對於靜態成員專業化,如果你不「T初始化成員,它被視爲一個專業化聲明,只是說:「哦,不要實例從主模板中的成員,因爲有一個特殊的定義在其他地方的定義「。應當提及的是,定義應該出現在一個.cpp文件(否則,您將獲得相反的:多重定義),並沒有初始化的聲明仍然應該放在頭文件。

現在正確的語法的確以下,應該出現在頭文件,但在.cpp文件

template<> int B<A, 1>::a[1] = { }; 

下還是應該出現在頭文件:

template<> int B<A, 1>::a[1]; 

這將作爲專業化聲明


從這個,它遵循的是你無法專注,只有具有默認的構造函數,是不可拷貝的成員,因爲你需要這句法:

// needs a copy constructor! 
template<> Type Class<Arguments>::member = Type(); 

的C++ 0x修復這樣的:

// doesn't anymore need a copy constructor 
template<> Type Class<Arguments>::member{}; 

對於我們之間的Standardese人,這裏的報價:

14.7.3/6

If a template, a member template or the member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.

14.7.3/15

An explicit specialization of a static data member of a template is a definition if the declaration includes an initializer; otherwise, it is a declaration. [Note: there is no syntax for the definition of a static data member of a template that requires default initialization.

template<> X Q<int>::x; 

This is a declaration regardless of whether X can be default initialized (8.5). ]

3.2/3

Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required.

3.2/5

There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.4) in a program [...]

的這對「一些模板參數沒有指定了」該限制意味着我們允許做以下,將其放入一個報頭(從而可能具有這種專業化的多個定義):

template<> template<typename T> 
Type OuterClass<int>::InnerClass<T>::StaticMember = 0; 

在你的情況下,你指定了所有的參數,使它不被允許多個定義的一個定義規則所覆蓋。