模板與重載

今天編程遇到一個問題,使用重載會簡單不少,但是如果輸入類型不在預設的類型中,又會出現問題。使用模板又比較麻煩。
所以突發奇想,模板和普通函數同時使用的時候會怎麼樣
比如如下代碼:

int type(int){
    return 0;
}

template<class T>
int type(T){
    return 1;
}

本以爲會報錯,畢竟class T裏是可以包含int的,但是沒想到居然成功了。所以查了查,模板同樣有重載。模板函數與非模板函數同樣可以共存。主要規則如下:

  1. 當不指定模板參數列表的時候,模板與非模板,優先匹配非模板
    就如同上面示例的代碼,當執行如下代碼的時候:

    cout << type(1) << endl;  //0
    

    返回值是0,也就是優先匹配了非模板函數。

  2. 當指定模板參數列表的時候,模板與非模板,匹配模板
    還是上面示例的代碼,當執行如下代碼的時候:

    cout << type<int>(1) << endl;  //1
    cout << type<>(1) << endl;     //1
    

    返回值是1,也就是匹配了模板函數。也就是說,當我指定模板參數列表的時候,即使列表爲空,也會優先匹配模板函數。

  3. 模板重載,優先匹配更準確的匹配
    對於如下代碼:

    template<class T>
    int type<T>{
        return 0;
    }
    template<class T>
    int type<T*>{
        return 1;
    }
    

    當我執行:

    char *ptr;
    cout << type(ptr) << endl;
    

    返回值是什麼呢?因爲此時對於模板T,既可以指char,也可以指char*。
    答案是,輸出的是1。因爲T*匹配的更精準(模板T匹配到的內容越少的越精準)。

  4. 特殊情況
    對於如下代碼:

    template<class T>
    int type<T>{
        return 0;
    }
    template<class T>
    int type<T&>{
        return 1;
    }
    

    當我執行:

    char ch;
    cout << type(ch) << endl;
    cout << type((char&)ch) << endl;
    

    這次,感覺兩個情況似乎一樣精準。那麼會調用哪個呢?
    沒錯!答案就是…………報錯;-D
    你自己都分不清還能指望編譯器分清楚?不存在的。

另外,調試的時候,當沒有模板函數的時候,還遇見一些重載時基本數據類型的隱式轉換,我也同樣總結一波。
對於char、int、float、double、unsigned char、unsigned int、long long這幾個類型而言:

  1. 首先,char和unsigned char優先轉換爲int型。其次轉換爲其他類型,但如果多個類型同時存在則會報錯。(其實這裏有點出乎我的意料,首先我以爲char和unsigned char會互相轉換,然後纔是int,其次我以爲unsigned int、long long int會和int同優先級)
  2. float優先轉換爲double,然後是其他類型。同優先級多個類型同時存在時報錯。
  3. int、double、unsigned int、long long不分優先級

對於指針和數組:

  1. 不同類型指針之間可以互相轉換,但是和其他基本類型不能互相轉換。
  2. char*、char[]可以轉換爲string,但不能反過來。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章