2012-10-02 106 views
4

如果我在非模板類中有一個成員函數模板並且想在類之外定義它 - 是否必須使用「內聯」?成員函數模板需要「內聯」

例子:

class A 
{ 
    template <class D> 
    void someMethod(D param); 
} 

template <class D> 
/* inline needed here? */ void A::someMethod(D param) 
{ 
} 

節標準的3.2.5說函數模板不擾定義規則下摔倒。在這方面,成員函數模板是一個函數模板嗎?

編輯:鏈接器不抱怨沒有內聯 - 但仍然 - 是否有效C++ 03?

編輯:

我已經學會爲止:海灣合作委員會(和assumingly其他的編譯器,太)出口隱含的模板實例爲弱符號,這意味着沒有衝突期間鏈接時會發生,如果他們在多個實例翻譯單位。由於弱符號不是標準的一部分 - 該標準以某種方式隱含地要求模板實例化以這種方式行爲,並且我能期待與其他標準符合編譯器/鏈接器組合的相同行爲嗎?

由於直列基本上忽略了優化,但允許在不同的翻譯單位這隱含轉化爲出口這些功能弱符號的功能的多個定義。這是否意味着聲明一個模板爲inline是多餘的?

+0

是的,編譯器不會抱怨。然而,並非所有滿足編譯器的都是有效的C++;)我們在這裏進行了討論,沒有人確定。 –

+1

編譯器無法投訴,因爲它一次只能看到一個翻譯單元,並且在兩個翻譯單元中定義了某些內容時會發生ODR違例。 – MSalters

+0

'inline'是否有任何語法意義?我一直認爲這只是編譯器的一個優化建議。 – Philipp

回答

0

無論成員函數模板是否爲函數模板,它們當然不是對象或非內聯函數,因此一個定義規則不適用。

但他們實際上是功能模板,並且對於非標準非應用模板的其他應用程序來說也是如此。

1

inline作爲一個關鍵字是爲了向編譯器提示標記爲這樣的函數是具有相同名稱的優化的好候選,並且作爲實現這種優化的幫助,它要求定義函數 - - 在使用它的每個CU中(即使連接器能夠執行相同的優化,編譯器在執行優化時也更容易,即使連接器能夠執行相同的優化,但它在20年內不常見前)。

您可能希望爲函數模板提供此提示,從而標記內聯函數模板定義。如果您不想提供該提示,則不需要內聯。

(現在已經過去了,只有內聯函數被考慮用於優化,但關鍵字還沒有達到register的命運,即編譯器通常會忽略它,因爲它的正式含義是防止採取變量的地址)。

+3

嗯......'inline'更多的是避免ODR違規,而不是暗示編譯器。在某個時間點,編譯器認爲這是一個很好的暗示,然後他們認爲人們並不知道編譯器開始忽視它作爲一種性能暗示。編譯器然後製作自己的非標準性能提示,以強制內聯。然後他們決定人們並不真的知道,即使那些非標準的表單通常也不會被編譯器忽略...... –

+0

@DavidRodríguez-dribeas,我的理解是它確實被認爲是一種暗示。不是作爲一種授權,而是還沒有被完全忽略(比如'register'),在評估應用優化的興趣的複雜函數中只是一個附加參數,並且可能是隨着時間的推移而降低重要性的一個參數(過程驅動不僅通過改進內聯算法,而且還包括爲了實現該目標而內聯使用的「僅頭部」庫的數量,降低其作爲優化的驅動程序的價值)。 – AProgrammer