★06.關(guān)于函數(shù)模板

定義:

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");
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容