5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
1

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

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

Author24 — интернет-сервис помощи студентам
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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.09.2011, 09:48
Ответы с готовыми решениями:

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

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

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

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

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

Решение

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

Добавлено через 41 минуту
Deviaphan, я сейчас читаю книгу: "Стивен Прата. Язык программирования С++. Лекции и упражнения. Учебник. Пер.с англ. (2005)." Там на стр. 365 есть пример кода (листинг 8.11), как специализация перекрывает шаблон. Отчего и вопрос возник.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
03.09.2011, 20:06 9
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 20:59  [ТС] 10
Написал, стал сравнивать мой код с тем, что в книге, и увидел, что там шаблон по другому задан. Мне кажется, что у меня в коде шаблон и специализация не стыкуются. Если задать шаблон так: 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
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
03.09.2011, 21:06 11
Цитата Сообщение от alsav22 Посмотреть сообщение
Мне кажется, что у меня в коде шаблон и специализация не стыкуются
Они не то, чтобы не стыкуются. Тогда бы компилятор возмутился. Просто непонятно, с чего бы тип box должен сопоставляться ссылке на него, если в шаблоне можно получить просто box, который в точности соответствует типу аргумента. В случае же специализации типом box вместо ссылки получается точное соответствие.
1
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 21:10  [ТС] 12
Цитата Сообщение от grizlik78 Посмотреть сообщение
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
Со ссылками. Скрин страницы прикрепляю.
Миниатюры
Почему не срабатывает специализация шаблона?  
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
03.09.2011, 21:12 13
Цитата Сообщение от alsav22 Посмотреть сообщение
Со ссылками. Скрин страницы прикрепляю.
Да, я недостаточно точно выразился. Я имел в виду, что не было специализации ссылочным типом, то есть <SomeType &>
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 21:33  [ТС] 14
Цитата Сообщение от 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
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
03.09.2011, 21:50 15
И правильно делает. 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
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 22:50  [ТС] 16
Благодарю!
0
03.09.2011, 22:50
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.09.2011, 22:50
Помогаю со студенческими работами здесь

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

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

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru