c++ - Function template materialization. I have been debugging for 1 hour. I have tried all means and the standard answers are correct, but it cannot be compiled.
高洛峰
高洛峰 2017-05-16 13:27:45
0
3
648

What I am doing is Question 6 of Chapter 8 on C++ Primer Plus
It is required to make two function templates, one for int double array, and one template to be concreted using char*[]
int and double There is no problem. I have been working on the concrete one for a long time. I don’t know why it can’t be compiled.
Then I wrote it again using ordinary functions and found that it can run normally. Then I worked on it for a long time and still couldn’t work, so I went online to find the answer. , I found that the format I wrote in answer
is basically the same. It just can’t be compiled

Error message: main.cpp:43:23: Error: template identifier 'maxn<const char [] of 'const char maxn(const char, int)' >'Does not match any template declaration template<>const char maxn<const char[]>(const char* x[], int n)

Code:

#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教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(3)
洪涛

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

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

Definition:

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;
}

You made three mistakes:

  • Incorrect specialization syntax

  • The two T types are inconsistent during specialization

  • Many pointers are not dereferenced


Idea:

Template declaration: template<typename T> T maxn(T x, int n);
调用:maxn(sx, 5)。其中变量sx的类型是const char *[5], that is, array type.

Since sx is an array type, the form of the template formal parameter is T,这里sx会被隐式转换成指针类型(array to pointer conversion)const char **,即T是const char **.

So the specialization should be
template<> const char **maxn(const char **x, int n);

PS: Intuitively, there should be a specialization of the reference version. But because T cannot deduce the reference type, no specialization of the reference version is called here. Of course, you can provide template parameters to call this specialization.

洪涛

According to my understanding, the maxn function should return the "largest" element in an array of length n, so I think the function declaration should be written like this:

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

Follow this statement, change your implementation, and it will compile.
The following code is simply modified based on your original code and compiled in vs2017 for reference:

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];
}
漂亮男人

You wrote the wrong special version.

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

Correct posture:

const char* maxn(const char* x[], int n);
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template