2013-04-07 159 views
3
  1. 在頭文件中定義的任何函數是否會自動內聯?
  2. 如果我在一個類中聲明一個函數,並使用關鍵字inline給外部定義,這個函數是內聯的嗎?如果是這樣,爲什麼這不違背內聯函數應該被聲明的機構?
+0

可能的重複:http://stackoverflow.com/questions/5131771/inline-keyword-in-member-function-definition – JBentley 2013-04-07 17:50:24

+0

@JBentley - 但是,該答案錯誤地應用ODR。 – 2013-04-07 18:04:55

+0

@Pete以什麼方式? – JBentley 2013-04-07 18:08:14

回答

1

inline是一個「提示」,只要編譯器不必遵守它。它可以使內聯不會內聯標記,也不必內聯內聯標記的內容。

因此,我的意思是你不應該依賴它。許多人建議你甚至不要使用它,因爲它是誤導性的。大多數現代編譯器完全忽視它。

唯一實際用途是允許您將靜態實現放入標題中。這是否是一件好事是有爭議的。

+0

)謝謝!這是否意味着當頭文件中的定義發生時,即使關鍵字inline沒有被使用,也會自動給出提示? – 2013-04-07 17:51:01

4

是否在頭文件中定義的任何函數都會自動內聯?

不,你應該讓任何在類內部通過手工定義的函數內聯。否則,很可能你會得到ODR違規(如果在多個翻譯單元中包含標題)。

ISO C++ 11

3.2一種定義規則

1:無翻譯單元應包含任何變量,函數,類型,枚舉類型,或模板的多於一個的定義。

[...]

4:每個程序應包含正好一個定義每個非內聯函數或變量,它是ODR使用的在該程序;不需要診斷。定義可以在程序中顯式出現,它可以在標準庫或用戶定義的庫中找到,或者(在適當的時候)它被隱式定義(見12.1,12.4和12.8)。內聯函數應在每個使用它的翻譯單元中定義。


,如果我在一個類中聲明的功能,並給外界使用inline關鍵字的定義,將這一功能是內聯?如果是這樣,爲什麼這不違背內聯函數應該被聲明的機構?

有幾種方法可以做到成員函數內聯:

首先,根據7.1.2/3:

一個類定義中所定義的函數是一個內聯函數。內聯說明符不應出現在塊範圍函數聲明中.90如果內聯說明符用於朋友聲明,則該聲明應爲定義,或者該函數以前已聲明爲內聯。

struct First 
{ 
    void first(){} 
}; 

第二,第三和第四,根據9.3/3:

一種直列成員函數(無論是靜態或非靜態)可能也是它的類定義之外被定義提供其在類定義中的聲明或在類定義之外的定義中聲明該函數爲內聯。 [注:名稱空間範圍內的類的成員函數具有外部鏈接。當地班級的成員職能(9.8)沒有聯繫。見3.5。末端音符]

struct STF 
{ 
    void second(); 
    inline void third(); 
    inline void fourth(); 
}; 

inline void STF::second(){} 
void STF::third(){} 
inline void STF::fourth(){} 
+2

問題可能只是多個相同事物的定義。 ODR,它要求當允許多個定義時,它們必須是相同的,而且,它不僅僅是非成員函數,而且還有任何沒有在類定義中定義的**函數 – 2013-04-07 17:55:53

+0

@PeteBecker。「This與ODR無關「 - 真的嗎?請您詳細說明ODR與」同一事物的多重定義不相關「是如何相關的? – 2013-04-07 18:00:10

+2

真的如果您有兩個同名的非內聯定義在這個問題的上下文中,ODR說當你有兩個相同函數的定義時,都標記爲「inline」,它們必須是「th」相同「。所以'inline int f(){return 3; } inline int f(){return 4; }'違反了ODR。 'int f(){return 3; } int f(){return 3; }'只是對同一事物的兩個定義,而且是一個錯誤。 – 2013-04-07 18:03:57

6

類定義中所定義的任何功能是內聯。任何標記爲inline的功能也都是內聯的。

class C { 
    int f() { return 3; } // inline 
    int g(); 
    int h(); 
} 


inline int C::g() { return 4; } // inline 
int C::h() { return 5; } // not inline 

如果所有這些代碼是在頭和頭被用來在一個以上的翻譯單元,你會得到一個抱怨C::h有一個以上的定義。 C::fC::g都可以,因爲它們是內聯的。現在這是inline的主要作用:允許在多個地方定義相同的函數(假設定義是「相同的」)。