-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375

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

03.12.2017, 16:07. Показов 4759. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Допустим у нас имеется шаблон функции такой, в угловых скобках которого содержатся как типовые параметры (с ударением на букве И), так и обычные параметры значения.

Возможна ли вообще написать специализацию для данного шаблона.
В принципе вопрос можно сформулировать и так: Не является ли наличие параметров значения, указываемых в угловых скобках этого шаблона функции, препятствием для создания специализации этого шаблона?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.12.2017, 16:07
Ответы с готовыми решениями:

Специализация шаблона функции
Как сделать специализированную функцию шаблон на тип int? У меня что-то не получается ..

Частичная специализация шаблона функции
Добрый день, помогите разобраться в чем проблема кода: template <int X, int Y> bool isSimple(){ return X%Y == 0 &&...

Почему не создается специализация шаблона функции
Почему это не работает и как правильно определить operator<< вне тела класса? #include <iostream> using namespace std; ...

14
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
03.12.2017, 16:11
Как бы специализация шаблона - это и есть задание иной его реализации для конкретных типов. http://ci-plus-plus-snachala.ru/?p=3937
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2017, 16:12
Цитата Сообщение от Просто Саша Посмотреть сообщение
Не является ли наличие параметров значения, указываемых в угловых скобках этого шаблона функции, препятствием для создания специализации этого шаблона?
не является.

специализируйте на здоровье
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 17:05  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
не является.
специализируйте на здоровье
Пока не выходит, вылазит сообщение об ошибке.

Добавлено через 6 минут
Пример вымученный.

Вот шаблон:

C++
1
2
3
4
5
6
7
8
9
10
template<int n, typename T> auto compare(T a, T b) -> int
{
    cout << n << endl;
    if (a > b)
        return 1;
    else if (a < b)
        return -1;
    else
        return 0;
}
Вот его специализация:

C++
1
2
3
4
5
6
7
8
9
10
template<> auto compare<int n, int *>(int * a, int * b) -> int
{
    cout << 3 * n << endl;
    if (*a > *b)
        return 1;
    else if (*a < *b)
        return -1;
    else
        return 0;
}
Пример не работает. В специализации подчеркивает n красной линией

Вот что выдает компилятор:

1>d:\myprojects\c++\deitla1\deitla1\deit la1.cpp(47): error C2146: синтаксическая ошибка: отсутствие ">" перед идентификатором "n"
1>d:\myprojects\c++\deitla1\deitla1\deit la1.cpp(48): error C2912: явная специализация; "int compare<int,int*>(int *,int *)" не является специализацией функции-шаблона
1>d:\myprojects\c++\deitla1\deitla1\deit la1.cpp(49): error C2065: n: необъявленный идентификатор

Компилятор: MS Visual C++ 2017

P.S. Когда убираю все, что связано с целочисленным параметром n из шаблона, специализации и определений, все работает прекрасно.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
03.12.2017, 17:28
Потому что шаблоны пишутся для типов, а не для указателей. Если хочешь использовать указатели - делай для них тип-обёртку

Добавлено через 46 секунд
Либо же в самом шаблоне нужно явно указывать указатели.

Добавлено через 11 минут
Цитата Сообщение от Просто Саша Посмотреть сообщение
Когда убираю все, что связано с целочисленным параметром n из шаблона,
потому что частичная специализация шаблона функции запрещена в С++. Нужно её полностью специализировать (указывать n явно).

А вот классы можно делать с частичной специализацией.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 17:31  [ТС]
Цитата Сообщение от TRam_ Посмотреть сообщение
Потому что шаблоны пишутся для типов, а не для указателей. Если хочешь использовать указатели - делай для них тип-обёртку
Да кто же Вам такую чушь сказал.
А что указатель уже перестал быть типом?

Добавлено через 1 минуту
Цитата Сообщение от TRam_ Посмотреть сообщение
Нужно её полностью специализировать (указывать n явно).
Ну Вы покажите как это делается.

Добавлено через 1 минуту
Что значит указывать n явно?
Если n убрать оттуда, то это уже будет не специализация, а перегрузка шаблона, или я что то не догоняю.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
03.12.2017, 17:34
Хотя... Насчёт указателей был неправ, извиняюсь.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 17:37  [ТС]
Ну напишите хотя бы одну специализацию для данного шаблона.
Я не прошу тело, напишите хотя бы ЗАГОЛОВОК.

Добавлено через 2 минуты
Или если это невозможно, то хотелось бы чтобы знающие люди написали просто, примерно следующее:
СПЕЦИАЛИЗАЦИЯ ШАБЛОНА ФУНКЦИИ, СОДЕРЖАЩЕГО ПОМИМО ТИПОВЫХ ПАРАМЕТРОВ ШАБЛОНА (С УДАРЕНИЕМ НА БУКВЕ И) ЕЩЁ И ПАРАМЕТРЫ ЗНАЧЕНИЙ НЕВОЗМОЖНА.

Так это или нет?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2017, 17:38
Цитата Сообщение от Просто Саша Посмотреть сообщение
template<> auto compare<int n, int *>(int * a, int * b) -> int
полная специализация подразумевает полную подстановку всех параметров шаблона.

например:
C++
1
template<> auto compare<10, int *>(int * a, int * b) -> int
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 17:49  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
полная специализация подразумевает полную подстановку всех параметров шаблона.
Ну а какой в ней тогда толк?
Имеется в виду для параметров значений.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2017, 17:52
Цитата Сообщение от Просто Саша Посмотреть сообщение
Ну а какой в ней тогда толк?
если в конкретном случае не видите толка - значит в этом конкретном случае,
нет нужды в полной специализации.
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 17:57  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
если в конкретном случае не видите толка - значит в этом конкретном случае,
Нет, не в конкретном случае дело, а вообще.
Если Вы знаете, что Ваша функция будет всегда вызываться с параметром 10, какой же это тогда параметр?

Добавлено через 1 минуту
Действительно я нашел в сети такое утверждение, что ЧАСТИЧНАЯ СПЕЦИАЛИЗАЦИЯ ФУНКЦИЙ В ОТЛИЧИЕ ОТ КЛАССОВ ЗАПРЕЩЕНА.

Но, хотелось уточнить следующее. Дело в том, что источники, в которых содержатся такое утверждение они 10-летней давности. Может быть что-то поменялось за это время?
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
03.12.2017, 18:03
Цитата Сообщение от Просто Саша Посмотреть сообщение
а перегрузка шаблона
в сравнении все три формы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
template<int n = 2, typename T> auto compare(T a, T b) -> int
{
    std::cout << n << std::endl;
    if (a > b)
        return 1;
    else if (a < b)
        return -1;
    else
        return 0;
}
 
template<> auto compare<2, int *>(int *a, int *b) -> int    // специализация
{
    std::cout << "2, int * " << std::endl;
    if (*a > *b)
        return 1;
    else if (*a < *b)
        return -1;
    else
        return 0;
}
 
auto compare(int *a, int *b) -> int    // перегрузка
{
    std::cout << "function" << std::endl;
    if (*a > *b)
        return 1;
    else if (*a < *b)
        return -1;
    else
        return 0;
}
Вначале будет проверяться на совпадение параметров перегрузка, потом специализация, потом шаблон.

Добавлено через 5 минут
Но зато можно определить шаблон с другим числом параметров, т.е. это не будет специализацией:

C++
1
2
3
4
5
6
7
8
9
10
template<int n> auto compare(int *a, int *b) -> int
{
    std::cout << n * 2 << std::endl;
    if (*a > *b)
        return 1;
    else if (*a < *b)
        return -1;
    else
        return 0;
}
0
-1 / 25 / 4
Регистрация: 27.11.2017
Сообщений: 375
03.12.2017, 18:05  [ТС]
Интересует только возможность написать вот так:

Цитата Сообщение от TRam_ Посмотреть сообщение
template<> auto compare<int n, int *>(int *a, int *b) -> int
Добавлено через 1 минуту
Ну а если подытожить, то все это можно описать примерно так:

Каждая специализация шаблона должны быть согласована с исходным шаблоном по формату того, что указывается в угловых скобках. Так, например, если в исходном шаблоне, внутри угловых скобок определяется один типовый параметр, то тогда и внутри угловых скобок должен содержаться ровно один тип, а не два и не три. Кроме того, следует помнить о том, что на настоящий момент частичная специализация шаблона функции не допускается. Это означает, что при специализации шаблона функции в определении этой специализации должны указываться значения для всех параметров, которые указаны между угловыми скобками в определении шаблона. Если такой параметр является параметром значения, то для него следует указать конкретное числовое значение.

Поправьте, плиз, если ошибаюсь.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.12.2017, 19:05
Цитата Сообщение от Просто Саша Посмотреть сообщение
а вообще.
полная специализация применяется,
когда необходимо реализовать какую то уникальную логику
для конкретного частной случая.
в подобных ситуациях нет никаких "вообще".

есть конкретные частные случаи под ключ задачи.

пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        template <class ch>
        constexpr ch* end(ch(&arr)[0]) noexcept
        {
            static_assert(
                ::is_same<char, char>::value,
                "[ERROR] length of array must be more that N > 0"
            );
        }
 
        template <class ch, size_t N>
        constexpr ch* end(ch(&arr)[N]) noexcept
        {
            return &arr[N];
        }
здесь общий случай: массив с количеством элементов N
и частный случай: массив с количеством элементов равным ноль.

Цитата Сообщение от Просто Саша Посмотреть сообщение
Может быть что-то поменялось за это время?
нет
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.12.2017, 19:05
Помогаю со студенческими работами здесь

Каким стандартом введена частичная специализация шаблона функции?
привет, сабж ясен из заголовка

Явная специализация шаблона функции - ошибка на этапе компиляции
Всем привет, читаю книгу С. Прата и пытаюсь скомпилировать шаблонную функцию с явной специализацией, но на этапе компиляции вылезают...

Error C2912: явная специализация не является специализацией функции-шаблона
Как исправить ошибку? #include &lt;iostream&gt; using namespace std; template &lt;typename t&gt; void PrintArray(t *arr, const int size) ...

C2912: специализация функции не является специализацией какого-то конкретного шаблона (в чём причина ошибки?)
Есть шаблонная функция, а есть её конкретная специализация для типа имени структуры box. Почему-то отказывается работать, ссылаясь на...

специализация шаблона
Добрый день! Хотелось бы сделать шаблонную функцию, у которой будет различная реализация в зависимости от того является ли шаблонный...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru