2012-04-18 51 views
10

是否O.K.在其主體外部定義類模板的虛函數?虛函數不能被內聯,但要避免在編譯單元多重定義它們應標明inline(假設模板頭文件將包含在多個源文件)。另一方面,編譯器可以自由忽略inline,所以這看起來有效。舉例來說,下面的代碼是正確的:模板定義之外的類主體

template <typename T> 
class C 
{ 
public: 
    virtual void f(T val); 
}; 

template <typename T> 
inline 
void C<T>::f(T val) 
{ 
    //definition 
} 

順便說一句,gcc(3.4.2)允許在定義函數f(T val)之前省略inline,但不能在常規類的類似函數之前。這僅僅是gcc的行爲嗎?

+5

您使用gcc * 3.4.2 *? – jpalecek 2012-04-18 14:19:58

+0

@jpalecek在這個特定的例子中,是的。 – doc 2012-04-18 14:22:03

+1

@doc - 虛函數*可以聲明爲「inline」(但這裏不需要)。編譯器在函數可以內聯的時候有點難以確定。 – 2012-04-18 15:58:24

回答

10

是的,沒關係,即使沒有inline它適用於普通的成員函數和相同靜態變量:

// everything in the header: 
template <class T> 
class A 
{ 
    static int i; 
}; 

template <class T> 
int A<T>::i=0; 

標準報價:(3.2/5)

可以有MOR Ë不是類型中的一種去音響nition(第9節),枚舉類型(7.2)中,用 外部連接(7.1.2),類模板(第14)的內聯函數,非靜態函數模板(14.5.6),靜態數據成員 類模板(14.5.1.3),成員函數類模板(14.5.1.1)或模板專用 某些模板參數沒有指定(14.7,14.5.5)提供的程序每個德音響nition 出現在二FF erent翻譯單元,並提供所述去音響nitions滿足以下要求...

的要求基本上說兩個定義必須是相同的。

它不工作,在普通班的情況。整個計劃中最多隻有一個定義。

+0

爲什麼有人投了這個答案:? – doc 2012-04-18 14:33:38

3

可以有定義的功能,只要它需要實例有問題的函數的代碼在編譯時的可見性(不鏈接時)的任何代碼。

這是很常見的模板分成2個文件,一個是傳統的標題,第二個是執行,與非模板函數並組織實施。唯一的區別是你需要#include模板實現文件以及頭部,當你想使用它。

4

您可以在同一頭文件中定義class定義之外的模板方法,而不使用inline,也不會收到多個定義錯誤。

這是因爲模板函數本身並不生成定義,如果它沒有完全專用。爲了證明我的觀點,以下內容:

void C<int>::f(int) 
{ 
} 

將導致鏈接錯誤,因爲函數在這種情況下的定義。 (前提是你有這個在多個翻譯單位如果選中它內聯:。

inline void C<int>::f(int) 
{ 
} 

錯誤不再出現