Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
#1

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

03.09.2011, 09:48. Просмотров 1285. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2011, 09:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему не срабатывает специализация шаблона? (C++):

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

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

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

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

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

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

15
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 09:57 #2
Для таких случаев лучше использовать не специализацию, а перегрузку.
0
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 15:18  [ТС] #3
Спасибо за совет, но вопрос остаётся.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 15:27 #4
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от alsav22 Посмотреть сообщение
но вопрос остаётся
Раз уж я всё равно достал книжку Саттера, то я и тут его процитирую:
Специализация шаблона функции никогда не участвует в перегрузке. Таким образом, любая написанная вами специализация не повлияет на результат разрешения перегрузки и выбор используемого шаблона. Это противоречит интуитивно ожидаемому поведению разрешения перегрузки...
...при разрешении перегрузки будет выбрана именно нешаблонная функция, как имеющая преимущество перед шаблоном.
3
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 17:47  [ТС] #5
Специализация шаблона функции никогда не участвует в перегрузке.
...при разрешении перегрузки будет выбрана именно нешаблонная функция, как имеющая преимущество перед шаблоном.
Я, конечно, абсолютный чайник, но в моём коде нет нешаблонной функции, и я понимаю, что если бы она была, то имела бы преимущество перед шаблоном. Если бы было несколько шаблонов, можно было бы говорить о перегрузке. В коде есть шаблон и специализация этого шаблона. Насколько я знаю, специализация шаблона имеет преимущество перед шаблоном. И это преимущество срабатывает, если типом данных специализации ставится box (структура). А если ссылка на стуктуру, то не срабатывает. Вот в этом я и пытаюсь разобраться. Почему не срабатывает при этом типе данных, и что нужно исправить, чтобы сработало?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
03.09.2011, 18:11 #6
Что во фразе "используй перегрузку вместо специализации" не понятно? Сказано же, при специализации функций перегрузка не определена, т.е. как компилятор пожелает, так и будет.
Кстати, при использовании шаблонных классов такой проблемы уже нет.
0
Kastaneda
Нарушитель
Эксперт С++
4673 / 2877 / 233
Регистрация: 12.12.2009
Сообщений: 7,309
Записей в блоге: 2
Завершенные тесты: 1
03.09.2011, 18:38 #7
Цитата Сообщение от alsav22 Посмотреть сообщение
И это преимущество срабатывает, если типом данных специализации ставится box (структура). А если ссылка на стуктуру, то не срабатывает. Вот в этом я и пытаюсь разобраться. Почему не срабатывает при этом типе данных, и что нужно исправить, чтобы сработало?
Если указать компилятору явно, что от него хотят, вот так:
C++
1
st3 = funk3<box&>(st, st2);
то будет вызвана спец.ф-ция.
1
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 19:36  [ТС] #8
Kastaneda, благодарю.

Добавлено через 41 минуту
Deviaphan, я сейчас читаю книгу: "Стивен Прата. Язык программирования С++. Лекции и упражнения. Учебник. Пер.с англ. (2005)." Там на стр. 365 есть пример кода (листинг 8.11), как специализация перекрывает шаблон. Отчего и вопрос возник.
0
grizlik78
Эксперт С++
1964 / 1457 / 119
Регистрация: 29.05.2011
Сообщений: 3,016
03.09.2011, 20:06 #9
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
0
alsav22
5425 / 4820 / 442
Регистрация: 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
grizlik78
Эксперт С++
1964 / 1457 / 119
Регистрация: 29.05.2011
Сообщений: 3,016
03.09.2011, 21:06 #11
Цитата Сообщение от alsav22 Посмотреть сообщение
Мне кажется, что у меня в коде шаблон и специализация не стыкуются
Они не то, чтобы не стыкуются. Тогда бы компилятор возмутился. Просто непонятно, с чего бы тип box должен сопоставляться ссылке на него, если в шаблоне можно получить просто box, который в точности соответствует типу аргумента. В случае же специализации типом box вместо ссылки получается точное соответствие.
1
alsav22
5425 / 4820 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 21:10  [ТС] #12
Цитата Сообщение от grizlik78 Посмотреть сообщение
alsav22, ну там же наверняка не было примеров со ссылками? Максимум указатели.
Со ссылками. Скрин страницы прикрепляю.
0
Миниатюры
Почему не срабатывает специализация шаблона?  
grizlik78
Эксперт С++
1964 / 1457 / 119
Регистрация: 29.05.2011
Сообщений: 3,016
03.09.2011, 21:12 #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Со ссылками. Скрин страницы прикрепляю.
Да, я недостаточно точно выразился. Я имел в виду, что не было специализации ссылочным типом, то есть <SomeType &>
0
alsav22
5425 / 4820 / 442
Регистрация: 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
grizlik78
Эксперт С++
1964 / 1457 / 119
Регистрация: 29.05.2011
Сообщений: 3,016
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
03.09.2011, 21:50
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2011, 21:50
Привет! Вот еще темы с ответами:

Специализация шаблона класса - C++
Имеется задание: Создать свой шаблонный класс – динамический массив (myvector). Создать методы этого класса. Инстанцировать для своего...

Специализация операции шаблона - C++
Доброго времени суток. Имеется шаблон: template&lt;class Type&gt;class Figures { /*...*/ public: /*...*/ void...

Явная специализация шаблона - C++
Здравствуйте. Не совсем разобрася с сабжем. Например, если есть кусочек кода: template &lt;typename T&gt; void func(T &amp;blue, T &amp;red); ...

Явная специализация шаблона - C++
Здравствуйте, подскажите, пожалуйста, почему не выполняется неявное приведение фактических параметров к формальным при вызове функции для...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru