首页  >  问答  >  正文

c++ - 函数模板具体化 已调试1小时,什么手段都试了,标准答案都对过了,就是无法编译

做的是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;
}
高洛峰高洛峰2686 天前591

全部回复(3)我来回复

  • PHP中文网

    PHP中文网2017-05-16 13:29:45

    声明: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推导不出引用类型,所以这里不会调用引用版本的特化。当然可以提供模板参数,来调用这个特化。

    回复
    0
  • PHP中文网

    PHP中文网2017-05-16 13:29:45

    按我理解,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];
    }
    

    回复
    0
  • 漂亮男人

    漂亮男人2017-05-16 13:29:45

    特化版本你写错了。

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

    正确姿势:

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

    回复
    0
  • 取消回复