c++ - 函數模板具體化 已調試1小時,什麼手段都試了,標準答案都對過了,就是無法編譯
高洛峰
高洛峰 2017-05-16 13:27:45
0
3
598

做的是c++ primer plus上的第八章第6題
要求做2個函數模板,分別對int double數組,還有一個模板具體化用char*[]
int 和double的是沒問題的, 具體化的那個,我弄了好久.不知道為什麼不能編譯.
然後我用普通函數寫了一遍,發現能正常運行.然後又搞了半天還是不行就上網找答案,發現我跟答案
寫的格式基本上一樣. 就是不能編譯

報錯訊息:main.cpp:43:23: 錯誤:'const char maxn(const char, int)'的範本識別碼'maxn<const char [] >'不符合任何範本宣告template<>const char maxn<const char[]>(const char* x[], int n)

程式碼:

#include <cstring>
#include <iostream>

using namespace std;

template<typename T>T maxn(T x, int n);
template<>const char* maxn<const char*[]>(const char* x[], int n);

/*
 * 模板函数针对不同类型数组 输出数组中最大的那个值
 */
int main(int argc, char** argv) {
    int ix[6] = {34, 12, 343, 1, 43, 31};
    double dx[4] = {1.34, 1231.2, 34.3, 44.23};
    const char* sx[5] = {"abcde", "fedcba", "abcdefg", "12345", "qwert"};
    cout << "ix[6] max: " << *maxn(ix, sizeof ix / sizeof ix[0]) << endl;
    cout << "dx[4] max: " << *maxn(dx, sizeof dx / sizeof dx[0]) << endl;
    cout << "sx[5] max_address: " << (int*) maxn(sx, 5) << endl;
    cout << "Press Enter To Exit..." << endl;
    cin.get();
    return 0;
}
//这个是我自己写的普通函数,能运行
//const char* maxn(const char* x[5],int n) {
//    const char* max_len = x[0];
//    for (int i = 0; i < n-1; i++) {
//        max_len = strlen(max_len) >= strlen(x[i + 1]) ? max_len : x[i + 1];
//    }
//    return max_len;
//}

template<>const char* maxn<const char*[]>(const char* x[], int n)
{
    const char* max_len = x[0];
    for (int i = 0; i < n - 1; i++) {
        max_len = strlen(max_len) >= strlen(x[i + 1]) ? max_len : x[i + 1];
    }
    return max_len;
}

template<typename T>
T maxn(T x, int n) {
    for (int i = 0; i < n - 1; i++) {
        x[i + 1] = x[i] > x[i + 1] ? x[i] : x[i + 1];
    }
    return x + n - 1;
}
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回覆(3)
洪涛

聲明:template<> const char **maxn(const char **x, int n);

呼叫:cout << "sx[5] max_address: " << (int*)*maxn(sx, 5) << endl;

定義:

template<>
const char **maxn(const char **x, int n)
{
    const char **max_len = x;
    for (int i = 0; i < n - 1; i++)
        max_len = strlen(*max_len) >= strlen(x[i + 1]) ? max_len : &x[i + 1];
    return max_len;
}

你犯了三個錯誤:

  • 特化語法不對

  • 特化時兩處T的類型不一致

  • 多處指標沒有解引用


思路:

模板聲明:template<typename T> T maxn(T x, int n);
调用:maxn(sx, 5)。其中变量sx的类型是const char *[5],即數組類型。

由於sx是陣列類型,模板形式參數的形式是T,这里sx会被隐式转换成指针类型(array to pointer conversion)const char **,即T是const char **

所以特化應當是
template<> const char **maxn(const char **x, int n);

PS:直覺上應該還可以有個引用版本的特化。但是因為T推導不出引用型,所以這裡不會呼叫引用版本的特化。當然可以提供模板參數,來呼叫這個特化。

洪涛

照我理解,maxn這個函數應該是想傳回長度為n的陣列中「最大」的那個元素,所以我覺得函數宣告應該寫成這樣:

template<typename T>T maxn(T x[], int n);
template<>const char* maxn<const char*>(const char* x[], int n);

按這個聲明,把你的實現改一下,就可以通過編譯了。
以下程式碼是在你原來程式碼基礎上做了簡單修改,在vs2017中編譯通過,供參考:

template<typename T>T maxn(const T x[], int n);
template<>const char* maxn<const char*>(const char* const x[], int n);

template<>const char* maxn<const char*>(const char* const x[], int n)
{
    const char* max_len = x[0];
    for (int i = 0; i < n - 1; i++) {
        max_len = strlen(max_len) >= strlen(x[i + 1]) ? max_len : x[i + 1];
    }
    return max_len;
}

template<typename T> T maxn(const T x[], int n) {
    for (int i = 0; i < n - 1; i++) {
        x[i + 1] = x[i] > x[i + 1] ? x[i] : x[i + 1];
    }
    return x[n - 1];
}
漂亮男人

特化版本你寫錯了。

template<>const char* maxn<const char*[]>(const char* x[], int n);

正確姿勢:

const char* maxn(const char* x[], int n);
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!