Специализация шаблона функции

295
17 июля 2017, 16:07

Здравствуйте люди добрые! Решаю задачку по плюсам, суть такая, что не могу написать специализацию шаблона функции - компилятор ругается. Суть задачки - при передачи числового массива (и кол-ва элементов, конечно) тупо найти наибольшее и вернуть, но доп. условие - эта самая специализация класса, чтобы при передаче массива указателей на char вернуть указатель на самую длинную строку.

#include <iostream>
#include <cstring>
using namespace std;
template <typename T> T maxn(const T [], int);          // шаблон
template <> char * maxn(const char * [], int);          // специализация
int main()
{
    int arInt[6] = {1, 2, 3, 777, 7, 9};
    double arDouble[4] = {228.1, 88.3, 1.0, 4.5};
    const char * arPtr[5] =
    {
        "qwertyuiop",
        "asdfdgjhdfkjdfjk",
        "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
        "skhkshjksg",
        "ksjdhfkbsfhksdjhfsdhfjk"
    };
    cout << "for arInt:" << endl;
    cout << "result: " << maxn(arInt, 6) << endl << endl;
    cout << "for arDouble:" << endl;
    cout << "result: " << maxn(arDouble, 4) << endl << endl;
    cout << "for arPtr:" << endl;
    cout << "result: " << maxn(arPtr, 5) << endl;
    return 0;
}
template <typename T> T maxn(const T arr[], int n)
{
    T result = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > result)
            result = arr[i];
    return result;
}
template <> char * maxn(const char * arr[], int n)
{
    char * result = arr[0];
    for (int i = 1; i < n; i++)
        if (strlen(arr[i]) > strlen(arr[i - 1]))
            result = arr[i];
    return result;
}

Ругается компилятор следующим образом:

8_6.cpp:20:20: ошибка: идентификатор шаблона «maxn<>» для «char* maxn(const char**, int)» не соответствует никакой декларации шаблона template <> char * maxn(const char * [], int); // специализация ^~~~

8_6.cpp:19:25: замечание: candidate is: template T maxn(const T*, int) template T maxn(const T [], int); // шаблон

Подскажите что не так делаю, ибо только осваиваю шаблоны эти, перерыл, а что не так - не пойму, хоть убей..

Answer 1

Вот так?

#include <vector>
#include <string>
#include <iostream>

template <class type_elem> 
type_elem max(const std::vector<type_elem> &v) {
    auto result = v[0];
    for(const auto &elem: v) {
        if (elem > result) {
            result = elem;
        }
    }
    return result;
}
template<>
std::string max(const std::vector<std::string> &v) {
    auto result = v[0];
    for(const auto &elem: v) {
        if (elem.length() > result.length()) {
            result = elem;
        }
    }
    return result;
}

int main() {
    std::vector<int> vint= {1, 2, 3, 777, 7, 9};
    std::vector<double> vdouble = {228.1, 88.3, 1.0, 4.5};
    std::vector<std::string> vstring = {
        "qwertyuiop",
        "asdfdgjhdfkjdfjk",
        "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
        "skhkshjksg",
        "ksjdhfkbsfhksdjhfsdhfjk"
    };
    std::cout << "vint max: " << max(vint) << std::endl;
    std::cout << "vdouble max: " << max(vdouble) << std::endl;
    std::cout << "vstring max: " << max(vstring) << std::endl;
    return 0;
}
Answer 2

Тип const char *[] соответствует типу T[] при T == const char *. Т.е. тип const char *[] - это массив с неконстантными элементами. Тип const char *[] никак не может соответствовать типу const T[] ни при каком T.

У вас в главном шаблоне параметр объявлен именно как const T[], а в явной специализации указан параметр типа const char *[]. Компилятор никак не сможет увидеть в этом явную специализацию главного шаблона, ибо не существует такого T, при котором const T[] будет соответствовать const char *[].

Если вы хотите, чтобы такое соответствие было возможным, специализация должна объявлять свой параметр как массив с константными элементами: const char *const []. При этом первый const опционален (он входит внутрь T).

Корректные варианты объявления явных специализаций данного шаблона могут выглядеть так

template <> char *maxn(char *const [], int);              // T == char *
template <> const char *maxn(const char *const [], int);  // T == const char *

но не так, как у вас.

READ ALSO
Проблема с TerminateThread

Проблема с TerminateThread

Создаю поток

231
Большие проблемы с загрузкой tmx-файлов

Большие проблемы с загрузкой tmx-файлов

ЗдравствуйтеНеобходимо загрузить и отрисовать карту в tmx-формате

325
выброс исключения без имени

выброс исключения без имени

Почему не отлавливается исключение?

289