定義:
template <typename T>
void fun(T t) {
}
特化
代碼
template<typename T>
void fun1(T t) {
std::cout << "fun1(T t)" << std::endl;
}
// 通過(guò)自動(dòng)推斷來(lái)確定模板參數(shù)T的函數(shù)模板特化
template<>
void fun1(int t) {
std::cout << "fun1(int t)" << std::endl;
}
template<typename T>
void fun2() {
T t;
std::cout << "fun2<T>()" << std::endl;
}
// 通過(guò)顯式說(shuō)明模板參數(shù)T為int的函數(shù)模板特化
template<>
void fun2<int>() {
int t;
std::cout << "fun2<int>()" << std::endl;
}
int main() {
fun1(0.0);
fun1(0);
fun2<double>();
fun2<int>();
return system("pause");
}
輸出
fun1(T t)
fun1(int t)
fun2<T>()
fun2<int>()
默認(rèn)模板實(shí)參【C++11】
template<typename T, typename F = int>
void fun() {
}
顯式指定模板實(shí)參
template <typename T>
void fun(T t) {
}
int main() {
fun<int>(0.0);
return system("pause");
}
顯式實(shí)例化
// 聲明函數(shù)模板實(shí)例化的作用是避免編譯期多次重復(fù)實(shí)例化,可以達(dá)到加塊編譯速度的效果
// 下述兩行代碼不能出現(xiàn)在同一文件
template void fun(int t); // 定義,代表此處將函數(shù)模板fun()實(shí)例化為fun<int>
extern template void fun(int t); // 聲明,代表承諾在別的文件有個(gè)fun<int>實(shí)例化
int main() {
fun<int>(1); // 此處實(shí)際上沒(méi)有實(shí)例化的過(guò)程,會(huì)復(fù)用已經(jīng)聲明的實(shí)例化
return system("pause");
}
尾置返回類(lèi)型的應(yīng)用
// 此處不得不使用尾置返回類(lèi)型,因?yàn)槲覀儾恢纀eg的解引用是什么類(lèi)型,而且beg知道參數(shù)列表才出現(xiàn)
template <typename T>
auto fun1(T beg, T end) -> decltype(*beg) {
return * beg;
}
// decltype會(huì)把(*beg)推斷為引用類(lèi)型,想要移除引用可以使用remove_reference<decltype(*beg)>::type
template <typename T>
auto fun2(T beg, T end) -> typename remove_reference<declval(*beg)>::type {
return * beg;
}
轉(zhuǎn)發(fā)型引用
如果模板參數(shù)是T &&的形式,則可以給它傳遞任何類(lèi)型的實(shí)參,詳情請(qǐng)查閱轉(zhuǎn)發(fā)型引用。
重載匹配問(wèn)題
template<typename T1>
void fun(T1 t1, T1 t2) {
std::cout << " 1" << std::endl;
}
template<typename T1, typename T2>
void fun(T1 t1, T2 t2) {
std::cout << "2" << std::endl;
}
void fun(int t1, double t2) {
std::cout << "3" << std::endl;
}
// 注意:特化本質(zhì)上是實(shí)例化一個(gè)模板,而非重載它,不會(huì)影響函數(shù)匹配
template<>
void fun(int t1, int t2) {
std::cout << "4" << std::endl;
}
// 注意:特化本質(zhì)上是實(shí)例化一個(gè)模板,而非重載它,不會(huì)影響函數(shù)匹配
template<>
void fun(int t1, double t2) {
std::cout << "5" << std::endl;
}
int main() {
// 不用經(jīng)過(guò)類(lèi)型轉(zhuǎn)換的函數(shù)匹配都叫精確匹配,有多個(gè)精確匹配版時(shí),根據(jù)如下規(guī)則選擇:
fun(1, 1.0); // 規(guī)則一:當(dāng)只有一個(gè)非模板函數(shù)精確匹配時(shí),優(yōu)先選擇此函數(shù)(1、2、3中選擇3)
fun(1.0, 1.0); // 規(guī)則二:規(guī)則一不滿(mǎn)足時(shí),優(yōu)先選擇更特例化的函數(shù)模板版本(1、2、3中選擇1)
fun(1, 1); // 規(guī)則二:規(guī)則一不滿(mǎn)足時(shí),優(yōu)先選擇更特例化的函數(shù)模板版本(1、2、3中選擇1的特化版本4)
// 規(guī)則三:上述規(guī)則都失效時(shí),調(diào)用有二義性。
return system("pause");
}