一、概念
java 或 C# 中叫泛型:generic,但是C++中叫templates,templatea則完全不同,也不能説完全不同,但是牛逼的多,比泛型和那些託管語言牛逼的多。模板有點像宏,它可以讓你做很多事情,但是泛型卻非常受制於類型系統,以及其他很多因素,模板templates要強大的多。模板是一個巨大、複雜的話題。
二、什麼是模板?
模板允許你定義一個可以根據你的用途進行編譯的模板,如果是有意義的話。你可以讓編譯器基於一套規則為你寫代碼。所謂模板,就是讓編譯器基於你給編譯器的規則為你寫代碼。
例如:當我用模板寫函數時,我實際上做的是,創建一個藍本。所以當我調用這個參數時,我可以指定特定的參數,這個參數決定了放入到模板中的實際代碼。這就決定了我如何使用這個函數。
- 未用模板示例:同樣的代碼重載多次
#include<iostream>
#include<string>
void Print(int a) {
std::cout << a << std::endl;
}
void Print(float a) {
std::cout << a << std::endl;
}
void Print(std::string a) {
std::cout << a << std::endl;
}
int main() {
Print(1);
Print(2.0f);
Print("Hello World");
std::cin.get();
}
- 使用C++ 模板
#include<iostream>
template<typename T>
void Print(T a) {
std::cout << a << std::endl;
}
int main() {
Print(1);
Print(2.0f);
Print("Hello World");
std::cin.get();
}
三、原理
如果你完全沒有使用、調用模板函數,那麼這個函數就不是真的存在,這個函數只是一個模板,只有當我們調用的時候,這個函數才被真正的創建,
eg:模板函數參數命名錯誤,Visual Studio編輯器並不會提示錯誤❌️,早期版本的Visual Studio 可build通過,新版本已不可通過
#include<iostream>
template<typename T>
void Print(T value) {
std::cout << valu << std::endl;
}
模板只有在它被調用時,才會被創建,因為它只是一個模板,不是實際的代碼。只有基於模板的使用情況,發送到編譯器,進行編譯後,才會具體化為真正的代碼。
四、模板的更多用處
模板絕不僅僅侷限於類型,也不侷限於函數。你可以創建一個整個的類基於模。實際上,大量的C++標準模板庫同樣完全使用了模板,
不用類型做模板參數:
#include<iostream>
template<int N>
class Array {
private:
int arr[N];
public:
int GetSize() const {
return N;
}
};
int main() {
Array<5> arr;
arr.GetSize();
std::cout << arr.GetSize() << std::endl;
std::cin.get();
}
改進類型版,更進一步模板化
#include<iostream>
template<typename T, int N>
class Array {
private:
T arr[N];
public:
int GetSize() const {
return N;
}
};
int main() {
Array<int, 5> arr;
arr.GetSize();
std::cout << arr.GetSize() << std::endl;
std::cin.get();
}
這種方式和C++的元編程(meta programming)很像,因為你可以看到,相比於實際編程,編譯器在編譯時,實際在編程。
很多遊戲工作室或軟件公司 實際上禁止使用模板,從來不用模板,我覺得這可能反應過度了,因為我任務模板非常有用,在日誌系統或其他的使用場景下,