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

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

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

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

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

Почему не создается специализация шаблона функции - 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++
Доброго всем времени суток! Помогите разобраться в следующей ситуации. Есть шаблон класса #include &lt;iostream&gt; using...

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

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

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

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

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

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

Почему не срабатывает инкремент? - C++
В комментарии показал вывод программы. Все переменные почему равны 2 Получается инкремент не оказывает никакого влияния? int a=0,...

Почему не срабатывает getline() ? - C++
Все привет почему то не срабатывает первый getline string comp_; cout &lt;&lt; &quot;1. Название: &quot; &lt;&lt; endl; getline(cin, comp_); cout...


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

Или воспользуйтесь поиском по форуму:
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2011, 22:50  [ТС]     Почему не срабатывает специализация шаблона? #16
Благодарю!
Yandex
Объявления
03.09.2011, 22:50     Почему не срабатывает специализация шаблона?
Ответ Создать тему
Опции темы

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