Введение: я хочу, чтобы явная сепиаклизация показала самую длинную строку, я думал, что это «Кармело Энтони», но результат — «Джордан». Я знаю, что общая версия шаблона используется вместо явной. Так что просто сравните значение точки (значение адреса), верно? Но как я мог увидеть «Кармело Энтони»? Спасибо за ответ на мой первый пост!
#include <iostream>
#include <cstring> //for strlen()
template <class T> //general template
T maxn (T arr[], int n);
template <> char * maxn<char *>(char * arr[], int n); //explicit specialization
int main()
{
using namespace std;
int intArr[6] = {1, 2, 34, 6, 9, 10};
double douArr[4] = {2.34, 90.6, -83.872, -0.23};
const char * arr[5] =
{
"Hello World",
"Kobe Bryant",
"Lebron James",
"Carmelo Anthony",
"Jordan"};
std::cout << maxn (intArr, 6) << std::endl;
std::cout << maxn (douArr, 4) << std::endl;
std::cout << maxn (arr, 5) << std::endl;
return 0;
}
template <class T>
T maxn (T arr[], int n)
{
T maxValue = arr[0];
for (int i = 1; i < n; i++)
{
maxValue = maxValue > arr[i] ? maxValue:arr[i];
}
return maxValue;
}
template <> char * maxn<char *>(char * arr[], int n)
{
char * p= arr[0]; //pointer p points to the present longest string
for (int i = 1; i < n; i++)
{
p = strlen (arr[i]) > strlen (p) ? arr[i] : p;
}
return p;
}
В дополнение к предыдущему ответу, вы можете специализировать оба const char *
а также char *
предоставляя простую вспомогательную функцию, которую будут вызывать обе версии:
#include <iostream>
#include <cstring> //for strlen()
template <class T> //general template
T maxn(T arr[], int n);
template <> const char * maxn<const char *>(const char * arr[], int n); //explicit specialization
template <> char * maxn<char *>(char * arr[], int n);
int main()
{
using namespace std;
int intArr[6] = { 1, 2, 34, 6, 9, 10 };
double douArr[4] = { 2.34, 90.6, -83.872, -0.23 };
const char * arr[5] =
{
"Hello World",
"Kobe Bryant",
"Lebron James",
"Carmelo Anthony",
"Jordan"};
char * arr2[5];
for (int i = 0; i < 5; ++i)
{
arr2[i] = new char[strlen(arr[i]) + 1];
strcpy(arr2[i], arr[i]);
}
std::cout << maxn(intArr, 6) << std::endl;
std::cout << maxn(douArr, 4) << std::endl;
std::cout << maxn(arr, 5) << std::endl;
std::cout << maxn(arr2, 5) << std::endl;
return 0;
}
template <class T>
T maxn(T arr[], int n)
{
T maxValue = arr[0];
for (int i = 1; i < n; i++)
{
maxValue = maxValue > arr[i] ? maxValue : arr[i];
}
return maxValue;
}
template<typename T>
T* charHelper(T *arr[], int n)
{
T* p = arr[0];
for (int i = 1; i < n; i++)
{
p = strlen(arr[i]) > strlen(p) ? arr[i] : p;
}
return p;
}
template <> char * maxn<char *>(char * arr[], int n)
{ return charHelper<char>(arr, n); }
template <> const char * maxn<const char *>(const char * arr[], int n)
{ return charHelper<const char>(arr, n); }
Выход:
34
90.6
Carmelo Anthony
Carmelo Anthony
Не обращайте внимания на очевидную утечку памяти в main
функция на данный момент.
Обратите внимание, что для arr
версия, const char*
специализация называется, а для arr2
версия, char *
версия называется.
Как предполагает @PaulMcKenzie, проблема заключается в отсутствии const
, Чтобы быть немного более подробным, ваша специализация шаблона для массивов указателей наconst
(то есть изменяемый) char
, Это говорит компилятору, что вы можете изменить передаваемые строки. Однако вы передаете массив const char *
т.е. неизменный строки. Компилятор не позволит вам вызвать функцию, которая может изменить данные на const
данные, поэтому он не будет использовать вашу специализацию, если вы не добавите const
,