問題描述
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 下編譯,但不鏈接:
It compiles under GCC 4.1, but does not link:
static.cpp:(.text._ZN1BI1ALi1EEC1Ev[B<A, 1>::B()]+0x5): undefined reference to `B<A, 1>::a'
如果可能的話,我更愿意保持專門的初始化,因為數組保存了一些特定于類型的數據.
I would prefer to keep initialisation specialised if it is possible, since the array holds some data specific to the type.
推薦答案
對于靜態成員特化,如果不初始化成員,則視為特化聲明,只說哦,不要從主模板實例化成員,因為在其他地方有專門的定義".需要說明的是,定義應該出現在.cpp文件中(否則,你會得到相反的結果:多個定義),沒有初始化器的聲明仍然應該放在頭文件中.
For static member specializations, if you don't initialize the member, it is taken as a specialization declaration, that just says "Oh, don't instantiate the member from the primary template, because there is a specialized definition somewhere else". It should be mentioned that the definition should appear in a .cpp file (otherwise, you will earn the opposite: multiple definitions), and the declaration without initializer should still be placed in the header file.
現在正確的語法確實如下,它應該不出現在頭文件中,而是出現在.cpp
文件中
Now the correct syntax is indeed the following, and it should not appear in a header file, but in a .cpp
file
template<> int B<A, 1>::a[1] = { };
以下內容仍應出現在頭文件中:
The following should still appear in a header file:
template<> int B<A, 1>::a[1];
這將作為專業化聲明.
由此可知,您不能特化一個只有默認構造函數且不可復制的成員,因為您需要以下語法:
From this, it follows that you can't specialize a member that only has a default constructor and is not copyable, because you would need this syntax:
// needs a copy constructor!
template<> Type Class<Arguments>::member = Type();
C++0x 修復了這個:
C++0x fixes this:
// doesn't anymore need a copy constructor
template<> Type Class<Arguments>::member{};
<小時>
對于我們當中的標準人來說,這里是引述:
For the Standardese people among us, here are the quotes:
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;
這是一個聲明,不管 X 是否可以默認初始化(8.5).]
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
:
一個類類型(第 9 條)、枚舉類型(7.2)、具有外部鏈接的內聯函數(7.1.2)、類模板(第 14 條)、非靜態函數模板(14.5)可以有多個定義.5)、類模板的靜態數據成員 (14.5.1.3)、類模板的成員函數 (14.5.1.1) 或在程序中未指定某些模板參數的模板特化 (14.7, 14.5.4)[...]
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 [...]
將此限制為未指定某些模板參數"意味著我們可以執行以下操作,將其放入標題中(因此可能具有此專業化的多個定義):
The restriction of this to "for which some template parameters are not specified" means that we are allowed to do the following, placing it into a header (thus possibly having multiple definitions of this specialization):
template<> template<typename T>
Type OuterClass<int>::InnerClass<T>::StaticMember = 0;
在您的情況下,您已經指定了所有參數,因此它不受允許多個定義的單一定義規則的約束.
In your case, you have all parameters specified, making it not being covered by the one defintion rule for allowing multiple definitions.
這篇關于專用模板類的靜態成員初始化的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!