创作缘由:
最近在学习C++, 这两天做练习时,发现下面这道题,自己写了代码进行测试,刚开始一直无法识别具体化函数模板,达不到预期效果(写了测试char*数组的具体化模板,但编译器一直无法识别,总是调用普通模板), 在网上搜了很多,几乎所有的答案都是“只写了函数模板或者写了函数模板和一个普通的测试char*数组的函数”, 不符完全合题目; 所以自己继续捣鼓研究, 最后发现是传参错误,以致于编译器进行识别时一直调用普通模板而不是具体化模板。在测试char*数组时不能直接定义成如下数组,因为此时将 arr 作为参数传入函数时,与具体化模板无法匹配,只能调用普通模板,所以达不到预期。最后,应按”正解代码“中的做法, 才能正确匹配具体化模板, 至于如何确定”编译器选择使用哪个函数模板“,鄙人也无法讲清楚,各位见谅,可自行搜索或狂击C++函数模板选择策略参考。
// 无法正常使用具体化模板的 char*数组
const char* arr[5] = {
"Hello!",
"I love you China!",
"CPython3.0“,
"Clang", "Let's study C++ together!"
};
题目:
6. 编写模板函数maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,
并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包
含4个double元素的数组来调用该函数。程序还包含一个具体化,它将char 指针数组和数组中的指
针数量作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串
的地址。使用由5个字符串指针组成的数组来测试该具体化。
正解代码:
#include <cstring>
#include <iostream>
using namespace std;
template <typename T>
T maxn(T arr[], int N);
template <> char *maxn<char*>(char *arr[], int N); // 显示具体化, 不需要再使用【template <typename T>】
int main(int argc, char *argv[])
{
int Iarr[6] = {3, 6, 9, 5, 8, 4};
cout << maxn(Iarr, 6) << endl;
double Darr[4] = {5.20, 9.9, 33.44, 13.14};
cout << maxn(Darr, 4) << endl;
char ptr1[] = "Hello!";
char ptr2[] = "I love you China!";
char ptr3[] = "CPython3.0";
char ptr4[] = "Let's study C++ together!";
char ptr5[] = "Clang";
char *arr[5] = {ptr1, ptr2, ptr3, ptr4, ptr5}; //可正常匹配具体化模板的 char*数组
cout << maxn(arr, 5) << endl;
return 0;
}
/* 【1】普通函数模板*/
template <typename T>
T maxn(T arr[], int N)
{
if (!arr)
exit(-1);
int i = 1;
T max_number = arr[0];
while (i < N)
{
if (arr[i] > max_number)
max_number = arr[i];
++i;
}
std::cout << "max_number = " << max_number << std::endl;
return max_number;
}
/* 【2】具体化函数模板*/
template <> char *maxn<char*>(char *arr[], int N)
{
if (!arr)
return NULL;
char *maxstr = arr[0];
int i = 1;
while (i < N)
{
if (strlen(arr[i]) > strlen(maxstr))
maxstr = arr[i];
++i;
}
std::cout << "max_str = " << maxstr << std::endl;
return maxstr;
}
运行结果: