Modern C++ - inline
inline 是一個C++聲明符,直譯爲⌈在行內⌋。
顧名思義,inline 希望編譯器在函式調用的地方直接插入函式的代碼。
這就是 C++ inline (內聯/內嵌)。
內聯函式
現代C++中,通常你並不需要手動聲明 inline ,這是因爲內聯只是一個⌈建議⌋。
如果函式內聯展開,可以避免函式調用的堆棧操作等開銷。
現代編譯器非常聰明,它可以自動選擇內聯候選函式。
即便你並沒有爲函式聲明inline,也有可能被編譯器內聯。
現代C++中 inline的意義已經變更爲允許重複定義。
inline如何解決重複定義?
在C++中,每個普通函式都需要一個且只能有一個函式定義。
當多個翻譯單元中有同一函式的多個定義時,將會引發鏈接錯誤(link err)。 (如果在一個翻譯單元中有多個定義將引發編譯錯誤,這與編譯原理相關)
inline聲明符可以允許同一個函式在多個翻譯單元中的重複定義,而不產生鏈接錯誤。
使其能夠在多個翻譯單元中使用 only header 的方式來共享函式定義
範例代碼:
//test.hpp
void func(){} //定義函式,Error.每個include此檔案的翻譯單元中都將有一個定義。
inline void func2(){} //內聯函式,Ok。允許了在多個翻譯單元中的重複定義。
void func3(); //僅聲明,Ok。需要在任意 一個 翻譯單元中定義,通常推薦對應的翻譯單元。
//test.cpp
#include "test.hpp"
//如果沒有定義func3將引發鏈接錯誤:找不到 __void __func3(...)...的定義。
void func3(){
func();//鏈接錯誤,重複定義 __void __func(...)...。
func2();//Ok,允許重複定義,每個翻譯單元調用自己的函式定義。
}
//main.cpp
#include "test.hpp"
int main(){
func();//鏈接錯誤,重複定義 __void __func(...)...。
func2();//Ok,允許重複定義,每個翻譯單元調用自己的函式定義。
func3();//Ok,鏈接時在其他翻譯單元中查找函式位址調用。
}
struct Test{
(inline) void print(){} //聲明即定義,這是隱式內聯的
};
constexpr (inline) int sum(int l,int r){ //編譯期函式,是隱式內聯的
return l+r;
}
template<typename T>
(inline) T make(){ //模板函式也是隱式內聯的
return T();
}
//...翻譯單元
翻譯單元是C++編譯時的單位,通常來說副檔名.cc .cpp表示這是一個翻譯單元。
翻譯單元由檔案本身 (如.cpp檔) 和透過 #include指令導入的標頭檔(如.h .hpp)或任意內容組成。
標頭檔通常不會作爲單獨的翻譯單元存在,它用於在多個翻譯單元的專案中共享聲明和定義。
除此之外還涉及include的實作方式,因爲include實際上做的就是將檔案中的內容完整拷貝過來。
這就是爲什麼需要注意重複定義的問題。
要在多個翻譯單元之間共享類/函式,一般會在標頭檔中聲明,在對應的一個翻譯單元中定義。
內聯變數
inline聲明符也可以用於變數(c++17起),其作用與函式內聯基本相同。
也是可以在不同翻譯單元中重複聲明變數。
// test.hpp
struct Test{
inline static int i = 0; //所有實例與翻譯單元中都是同一個對象
}
inline int func(){
static int i = 0; // 所有翻譯單元中都是同一個對象
return ++i;
}
void call();
// test.cpp
#include "test.hpp"
void call(){
Test t2;// 實例2
++t2.i; // 結果2
int i = func(); // 結果2
}
// main.cpp
#include "test.hpp"
int main(){
Test t1;// 實例1
++t1.i; // 結果1
int i = func(); // 結果1
call();
}小結
inline聲明符允許了多個翻譯單元中同時存在 同一個函式/變數的定義,是實現only header的方法。
類中定義的成員函式、模板與constexpr不需要聲明inline,因爲其是隱式內聯的。
inline的函式與變數同時有static變數存在時,不會影響靜態變數的存在,保證保持全局唯一。
參閱:
博主使用的是什么博客系统和主题?非常适合我的审美呢!
我這裏是typecho喔~ 主題是這個:https://github.com/youranreus/G 。可能有客製化修改

谢谢博主,我准备去尝试一下!