Что не так с этим шаблоном

Я делаю С++ 6-е издание, 6-е упражнение 8-й главы. У меня есть вопросы по этому шаблону. Я не знаю, почему он всегда показывает последнюю строку, а не показывает строку максимальной длины.

#include <iostream>
#include <cstring>

//8.6

using namespace std;

template <typename T> T Maxn(T *,int);

template <>  char * Maxn<>(char **,int );

int main()
{
    double arr_1[5] = { 0.0,3.0,1.0,4.0,5.0 };
    cout << "double max: " << Maxn(arr_1,5) << endl;

    int arr_2[4] = { 3,4,1,0 };
    cout << "int max: " << Maxn(arr_2, 4) << endl;

    const char *arr_3[4] = { "sdf","tttq","ttttrrsdss" ,"q12221"};  
    cout << "char max:" << Maxn(arr_3, 4) << endl;

    return 0;
}

template <typename T>
T Maxn(T *p,int n)
{
    T max = p[0];
    for (int i = 0; i < n; i++)
    {
        if (p[i] > max)
            max = p[i];
    }

    return max;
}

template <> char * Maxn<>(char **p, int n)
{
    char * max = p[0];
    for (int i = 0; i < n; i++)
    {
        if (strlen(p[i]) > strlen(max))
        {
            max = p[i];
        }
    }
    return max;
}

Каким должен быть шаблонный тип? Вам вообще нужен шаблон?

πάντα ῥεῖ 30.05.2019 17:51

Я сомневаюсь, что это компилируется. Не только из-за странной попытки объявления шаблона, но и из-за того, что вы отбрасываете const. Как вы это строите? Вы уверены, что ваша сборка не потерпела неудачу, и вы действительно использовали старый двоичный файл?

François Andrieux 30.05.2019 17:52

Почему у вас есть шаблон, который не заботится о типах? Это не имеет никакого смысла.

tadman 30.05.2019 17:55

Обратите внимание, что ожидаемый параметр — char **, а arr_3 — типа char const **.

Michael Doubez 30.05.2019 17:56
Я делаю С++ 6-е издание, 6-е упражнение 8-й главы. Возможно, вам следует указать точное название книги.
drescherjm 30.05.2019 17:58

Это не шаблон, а специализация шаблона. Пожалуйста, покажите также шаблон.

sebrockm 30.05.2019 18:00

Я добавил весь код сейчас.

Zhiqiang Yang 30.05.2019 18:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Тип arr_3 — const char *, но не char *:

const char *arr_3[4] = { "sdf","tttq","ttttrrsdss" ,"q12221"};  

, так называется первая реализация Maxn, где strlen не используется.

Да, понятно... Но как я могу инициировать char *arr_3[4] = { "sdf","tttq","ttttrrsdss","q12221"} без использования const? Я не могу скомпилировать его без const char *.

Zhiqiang Yang 30.05.2019 18:23

На самом деле вам не нужна реализация Maxn для char *. Так что перепишите его для const char *, и ваш код будет работать так, как вы ожидаете.

gimme_danger 30.05.2019 18:31
Ответ принят как подходящий

Вы должны просто начать использовать отладчик или, как минимум, вы можете посетить свой код с помощью отладки printf. Вы увидите, что ваша специализация char* никогда не используется!

Причина:

Ваш тип данных для «строк» ​​— const char*, который лучше подходит для первого шаблона, чем для вашей специализации, поэтому просто называется первая версия шаблона. И это сравнивает теперь адрес строк. Если ваш компилятор помещает строки в порядке, представленном в исходном коде, вы всегда будете видеть в качестве результата последнюю строку, так как она имеет самый высокий адрес.

Просто используйте:

template <> const char * Maxn<>(const char **p, int n)
{
    const char * max = p[0];
    for (int i = 0; i < n; i++)
    {
        if (strlen(p[i]) > strlen(max))
        {
            max = p[i];
        }
    }
    return max;
}

Кстати: в вашем коде есть несколько потоков эффективности. Вы сравниваете на первом шаге два раза одно и то же значение, которое не требуется.

Другие вопросы по теме