外部模板 傳統 C++ 中,模板只有在使用時才會被編譯器實例化。換句話說,只要在每個編譯單元(文件) 中編譯的代碼中遇到了被完整定義的模板,都會實例化。這就產生了重覆實例化而導致的編譯時間的增加。並且,我們沒有辦法通知編譯器不要出發模板實例化。 C++11 引入了外部模板,擴充了原來的強制編譯器在特... ...
外部模板
傳統 C++ 中,模板只有在使用時才會被編譯器實例化。
換句話說,只要在每個編譯單元(文件) 中編譯的代碼中遇到了被完整定義的模板,都會實例化。
這就產生了重覆實例化而導致的編譯時間的增加。
並且,我們沒有辦法通知編譯器不要出發模板實例化。
C++11 引入了外部模板,擴充了原來的強制編譯器在特定位置實例化模板的語法,
使得能夠顯式的告訴編譯器何時進行模板的實例化:
template
class
std::vector<MagicClass>; // 強行實例化 |
尖括弧 ">"
在傳統 C++ 的編譯器中, >> 一律被當做右移運算符來進行處理。
但實際上我們很容易就寫出了嵌套模板的代碼:
std::vector<std::vector<int>> mtx; |
這在傳統C++編譯器下是不能夠被編譯的
C++11 開始,連續的右尖括弧將變得合法,並且能夠順利通過編譯。
甚至於下下麵這種寫法都能夠通過編譯:
template<bool
T> SuckType; |
類型別名模板
在瞭解類型別名模板之前,需要理解『模板』 和『類型』 之間的不同。
仔細體會這句話:模板是用來產生類型的。
在傳統 C++中, typedef 可以為類型定義一個新的名稱,但是卻沒有辦法為模板定義一個新的名稱。
因為,模板不是類型。例如:
template<typename
T, typename
U> |
C++11 使用 using 引入了下麵這種形式的寫法,並且同時支持對傳統typedef 相同的功效:
typedef
int(*process)(void *); |
變長參數模板
在 C++11 之前,無論是類模板還是函數模板,都只能按其指定的樣子,接受一組固定數量的模板參數;
而 C++11 加入了新的表示方法,允許任意個數、任意類別的模板參數,
同時也不需要再定義時將參數的個數固定。
template<typename... Ts> class
Magic; |
既然是任意形式,所以個數為0的模板參數也是可以的:
class Magic<> nothing;
如果不希望產生的模板參數個數為0,可以手動的定義至少一個模板參數:
template<typename Require, typename... Args> class Magic; |