Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587

Почему не срабатывает специализация шаблона?

03.09.2011, 09:48. Показов 2152. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <clocale>
using namespace std;
struct box
{
    char mak[40];
    float m;
    float n;
    float y;
    float z;
};
template <class any> any funk3(any x, any y);// Шаблон.
template <> box& funk3<box&>(box &x, box &y);// Специализация.
int main()
{   
    setlocale(0, "");
    box st = 
    {
        "12345",
        1.1f,
        2.2f,
        3.3f,
        4.4f
    };
    box st2 = 
    {
        "12345",
        1.2f,
        2.3f,
        3.4f,
        4.5f
    };
    int a = 3, b = 4;
    cout << "Первый вызов  " << funk3(a, b) << endl;
    box st3;
    st3 = funk3(st, st2);
    cout << "Второй вызов  " << st3.z << endl;
    system ("pause");
    return 0;
}        
template <class any> any funk3(any x, any y)
{
    any z = x;
    cout << "Шаблон" << endl;
    return z;
}
template <> box& funk3<box&>(box &x, box &y)
{
    cout << "Специализация" << endl;
    return y;
}
Подскажите, пожалуйста, почему не срабатывает специализация при втором вызове функции funk3? Если специализацию переписать как: template <> box funk3<box>(box x, box y), то срабатывает.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.09.2011, 09:48
Ответы с готовыми решениями:

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

Специализация шаблона для char * (рабочий код, но непонятно почему)
Явное определение специализации – это такое определение, в котором за ключевым словом template следует пара угловых скобок &lt;&gt;, а за...

Специализация шаблона
Пытаюсь специализировать шаблон для типа float, но не получается. В чем проблема? Компилятор: 1&gt;TemplateArr.obj : error LNK2005:...

15
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 09:57
Для таких случаев лучше использовать не специализацию, а перегрузку.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 15:18  [ТС]
Спасибо за совет, но вопрос остаётся.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 15:27
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от alsav22 Посмотреть сообщение
но вопрос остаётся
Раз уж я всё равно достал книжку Саттера, то я и тут его процитирую:
Специализация шаблона функции никогда не участвует в перегрузке. Таким образом, любая написанная вами специализация не повлияет на результат разрешения перегрузки и выбор используемого шаблона. Это противоречит интуитивно ожидаемому поведению разрешения перегрузки...
...при разрешении перегрузки будет выбрана именно нешаблонная функция, как имеющая преимущество перед шаблоном.
3
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 17:47  [ТС]
Специализация шаблона функции никогда не участвует в перегрузке.
...при разрешении перегрузки будет выбрана именно нешаблонная функция, как имеющая преимущество перед шаблоном.
Я, конечно, абсолютный чайник, но в моём коде нет нешаблонной функции, и я понимаю, что если бы она была, то имела бы преимущество перед шаблоном. Если бы было несколько шаблонов, можно было бы говорить о перегрузке. В коде есть шаблон и специализация этого шаблона. Насколько я знаю, специализация шаблона имеет преимущество перед шаблоном. И это преимущество срабатывает, если типом данных специализации ставится box (структура). А если ссылка на стуктуру, то не срабатывает. Вот в этом я и пытаюсь разобраться. Почему не срабатывает при этом типе данных, и что нужно исправить, чтобы сработало?
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 18:11
Что во фразе "используй перегрузку вместо специализации" не понятно? Сказано же, при специализации функций перегрузка не определена, т.е. как компилятор пожелает, так и будет.
Кстати, при использовании шаблонных классов такой проблемы уже нет.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
03.09.2011, 18:38
Цитата Сообщение от alsav22 Посмотреть сообщение
И это преимущество срабатывает, если типом данных специализации ставится box (структура). А если ссылка на стуктуру, то не срабатывает. Вот в этом я и пытаюсь разобраться. Почему не срабатывает при этом типе данных, и что нужно исправить, чтобы сработало?
Если указать компилятору явно, что от него хотят, вот так:
C++
1
st3 = funk3<box&>(st, st2);
то будет вызвана спец.ф-ция.
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 19:36  [ТС]
Kastaneda, благодарю.

Добавлено через 41 минуту
Deviaphan, я сейчас читаю книгу: "Стивен Прата. Язык программирования С++. Лекции и упражнения. Учебник. Пер.с англ. (2005)." Там на стр. 365 есть пример кода (листинг 8.11), как специализация перекрывает шаблон. Отчего и вопрос возник.
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.09.2011, 20:06
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 20:59  [ТС]
Написал, стал сравнивать мой код с тем, что в книге, и увидел, что там шаблон по другому задан. Мне кажется, что у меня в коде шаблон и специализация не стыкуются. Если задать шаблон так: template <class any> any& funk3(any &x, any &y);, а специализацию так: template <> box& funk3<box>(box &x, box &y);, то всё работает. Если же шаблон такой: template <class any> any funk3(any x, any y);, то специализация: template <> box funk3<box>(box x, box y);.
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.09.2011, 21:06
Цитата Сообщение от alsav22 Посмотреть сообщение
Мне кажется, что у меня в коде шаблон и специализация не стыкуются
Они не то, чтобы не стыкуются. Тогда бы компилятор возмутился. Просто непонятно, с чего бы тип box должен сопоставляться ссылке на него, если в шаблоне можно получить просто box, который в точности соответствует типу аргумента. В случае же специализации типом box вместо ссылки получается точное соответствие.
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 21:10  [ТС]
Цитата Сообщение от grizlik78 Посмотреть сообщение
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
Со ссылками. Скрин страницы прикрепляю.
Миниатюры
Почему не срабатывает специализация шаблона?  
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.09.2011, 21:12
Цитата Сообщение от alsav22 Посмотреть сообщение
Со ссылками. Скрин страницы прикрепляю.
Да, я недостаточно точно выразился. Я имел в виду, что не было специализации ссылочным типом, то есть <SomeType &>
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 21:33  [ТС]
Цитата Сообщение от grizlik78 Посмотреть сообщение
Просто непонятно, с чего бы тип box должен сопоставляться ссылке на него, если в шаблоне можно получить просто box, который в точности соответствует типу аргумента.
Это понятно. Но почему тогда, если передавать в качестве аргументов не box, а ссылку на box, что точно соответствует специализации, то она всё равно не срабатывает? Если добавить:
C++
1
2
3
4
box &st3_p = st3;
box &st_p = st;
box &st2_p = st2;
st3_p = funk3(st_p, st2_p);
то всё равно специализация не работает.
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
03.09.2011, 21:50
И правильно делает. st_p это просто синоним st, с точно такими же свойствами. Единственный известный мне способ, заставить шаблонную функцию принимать переменные по ссылке (если ссылка не указана явно в прототипе) это явно указать аргумент шаблона, то есть funk3<box&>()

Добавлено через 10 минут
В качестве примера, можно рассмотреть такой код:
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
#include <iostream>
 
template <typename T>
T f(T x)
{
    ++x;
    return x;
}
 
using namespace std;
 
int main()
{
    int a = 5;
    int &b = a;
    cout << f(a) << endl;
    cout << "a = " << a << endl;
 
    cout << f(b) << endl;
    cout << "a = " << a << endl;
    
    cout << f<int&>(a) << endl;
    cout << "a = " << a << endl;
 
    return 0;
}
Меня бы очень удивило, если бы после вызова f(b) изменилась бы переменная a. Ведь это b является ссылкой на a, а не x.
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 22:50  [ТС]
Благодарю!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
03.09.2011, 22:50
Помогаю со студенческими работами здесь

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

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

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

Специализация шаблона
Привет, у меня есть вот такой шаблон дерева: template &lt;typename T = int&gt; class Tree{ struct TreeItem{ // элемент дерева ...

Специализация шаблона
Всем доброго вечера! Возникает непонятная ошибка при создании специализации родового класса cl. В строке 10: template class...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Киев стоит - украинская песня
zorxor 28.01.2026
wfWdiRqdTxc О Господи, Вечный, Ты . . . Я помоги, Бесконечный. . . Я прошу Ты. . . Я погибаю, спаси. . . Я прошу Тебя Вечный. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru