Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
1

Template specializations

02.06.2019, 15:43. Показов 1991. Ответов 10

Author24 — интернет-сервис помощи студентам
Всем добрый день!
Читаю книгу С. Праты C++ Primer Plus, 6th edition. Возникли вопросы по теме template specializations.
Хочу убедится, что правильно усвоил материал а также задать вопрос про explicit instantation.

Не по теме:

Перевод к терминам не нашел :(


Как я узнал, специализаций (specializations) в С++ бывает три вида:
  • implicit instantation
  • explicit instantation
  • explicit specialization

Не по теме:

В инете видел, что есть еще и четвертый


0. Создал шаблонный класс Animal и написал функцию Swap (ничем не отличается от std::swap).
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Animal
{ // Все поля публичные.
public: 
    std::string name_;
    int age_;
    int weight_;
public:
    void print(); // Вывести поля класса.
};
 
void Animal::print()
{
    using namespace std; // Объект cout нуждается в namespace std.
    cout << " " << name_ << ", " << age_ << " y.o., " << weight_ << " kg " << endl;
}
 
template <typename T> void Swap(T &a, T &b) // Обменять два идентификатора значениями,
{ // используя шаблон.
    T temp = a;
    a = b;
    b = temp;
}

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

Кликните здесь для просмотра всего текста
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
52
53
54
55
56
57
58
59
#include <iostream>
#include <string>
 
class Animal
{ // Все поля публичные.
public: 
    std::string name_;
    int age_;
    int weight_;
public:
    void print(); // Вывести поля класса.
};
 
void Animal::print()
{
    using namespace std; // Объект cout нуждается в namespace std.
    cout << " " << name_ << ", " << age_ << " y.o., " << weight_ << " kg " << endl;
}
 
template <typename T> void Swap(T &a, T &b) // Обменять два идентификатора значениями,
{ // используя шаблон.
    T temp = a;
    a = b;
    b = temp;
} 
 
template<> void Swap <Animal> (Animal &a, Animal &b) // Explicit specialization для типа Animal.
{ // Поменять между собой поля age и weight.
    // Вызвать шаблонный прототип метода
    Swap(a.age_, b.age_); // swap integer,
    Swap(a.weight_, b.weight_); // swap integer.
    // Эти два вызова являют собой Implicit instantation, потому что создают функцию определения для типа int.
}
 
int main()
{
    // Создать два объекта типа Animal:
    Animal cat = { "cat", 3, 4 }; // cat и
    Animal dog = { "dog", 2, 5 }; // dog.
 
    Swap(cat, dog); // Обменять между собой поля age and weight,
    // имена оставить не тронутыми.
 
    // Вывести информацию об объектах.
    cat.print(); 
    dog.print();
 
    int apples = 10;
    int pears = 7;
 
    Swap(apples, pears); // Implicit instantation,
    // Создается функция определения void Swap(int, int) (для типа данных int).
 
    std::cout << " apples: " << apples << std::endl;
    std::cout << " pears: " << pears << std::endl;
 
    system("pause");
    return 0;
}


2. Я описал только две специализации - Implicit instantation и Explicit specialization. А вот на на попытке введения Explicit instantation возникла проблема. Я руководился примером Праты из его книги, но, почему то компилятор ругается на следующую запись (добавляю в main() и ничего не меняю):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    // ...
    template void Swap<int>(int &, int &); // Explicit instantiation для типа int,
    // реализовываем функцию Swap для этого типа (или нет?).
 
    // ...  
 
    Swap(apples, pears); // Implicit instantation,
    // Создается функция определения void Swap(int, int) (для типа данных int).
 
    std::cout << " apples: " << apples << std::endl;
    std::cout << " pears: " << pears << std::endl;
    
    // ...
 
    system("pause");
    return 0;
}


И в итоге получаю такие ошибки:
Код
явное создание экземпляра в текущей области не допускается.
явное создание экземпляра шаблона может происходить только в области видимости пространства имен.
Итак вот то, что я хотел спросить (подведу итог):
  1. Правильно ли я понял специализации шаблонов (см. комментарии к коду)?
  2. Почему возникает ошибка при попытке создания explicit instantation? Я что-то не так делаю?

Заранее огромное спасибо
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.06.2019, 15:43
Ответы с готовыми решениями:

Ошибки: 1) use of class template requires template argument list 2) 'T' : undeclared identifier
Решил подправить свой класс с использованием шаблонов, но столкнулся со следующим косяком. Если я...

Template definition of non-template при использовании частичной спецификации шаблонов
Всем привет! Есть задача написать шаблон класса, принимающего в качестве параметров типа шаблон и...

'MyQueue' : use of class template requires template argument list
Написал код про шаблоны. Не могу понять почему выводит ошибку во время наследования класса. ошибки...

В чем различие template <typename T> от template <class T> ?
Добрый день ! Заметил в новых книгах применение записи template &lt;typename T&gt; вместо template...

10
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
02.06.2019, 15:49  [ТС] 2
Вот весь код, включая Explicit instantation.

Не по теме:

Комментарии на английском языке

Вложения
Тип файла: rar code.rar (770 байт, 5 просмотров)
0
Эксперт С++
8971 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.06.2019, 16:05 3
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
code.rar
ты же не думаешь, что кто-то специально ради тебя
будет накатывать проприетарный софт к себе на машинку?

нормальные люди пакуют в общедоступный zip.
0
Неэпический
18100 / 10686 / 2061
Регистрация: 27.09.2012
Сообщений: 26,899
Записей в блоге: 1
02.06.2019, 16:08 4
Цитата Сообщение от hoggy Посмотреть сообщение
будет накатывать проприетарный софт к себе на машинку?
7zip, unRAR
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.06.2019, 16:19 5
C++
1
2
3
4
int main()
{
    // ...
    template void Swap<int>(int &, int &);
это попытка локального объявления функции. Шаблоны тут не при чём.
1
215 / 162 / 52
Регистрация: 09.12.2017
Сообщений: 520
02.06.2019, 16:26  [ТС] 6
Цитата Сообщение от IGPIGP Посмотреть сообщение
это попытка локального объявления функции
Тоже так думаю. Но, Прата приводит подобный пример (если нужно, то могу скинуть книгу и указать страницу, на которой он это пишет).
А как тогда правильно реализовать explicit instantiation ?
Спасибо !
0
Неэпический
18100 / 10686 / 2061
Регистрация: 27.09.2012
Сообщений: 26,899
Записей в блоге: 1
02.06.2019, 16:46 7
JohnBlack123, вынести явное инстанцирование из main
1
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.06.2019, 17:15 8
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Но, Прата приводит подобный пример
Там очень много опечаток.

Добавлено через 5 минут
Цитата Сообщение от JohnBlack123 Посмотреть сообщение
А как тогда правильно реализовать explicit instantiation ?
Нужно сделать как советует Croessmah, плюс добавить тело функции создав полное определение. Вообще, есть достаточно простое но важное отличие между специализациями шаблонов класса и шаблонных функций. Шаблонные функции нельзя специализировать частично. Зато функции поддерживают перегрузку (разным набором параметров). Вообще, вывод аргументов шаблонов это едва ли не самая сложная область плюсов.
0
Неэпический
18100 / 10686 / 2061
Регистрация: 27.09.2012
Сообщений: 26,899
Записей в блоге: 1
02.06.2019, 17:50 9
IGPIGP, не нужно определение. Это явное инстанцирование.
1
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
02.06.2019, 18:37 10
Цитата Сообщение от Croessmah Посмотреть сообщение
Это явное инстанцирование.
Я спутал с явной специализацией. Каюсь. Ну-да. Для получения кода на который, например, можно взять адрес принудительно-предварительное явное инстанцирование.
0
Вездепух
Эксперт CЭксперт С++
12771 / 6653 / 1791
Регистрация: 18.10.2014
Сообщений: 16,817
02.06.2019, 19:29 11
Лучший ответ Сообщение было отмечено JohnBlack123 как решение

Решение

Цитата Сообщение от JohnBlack123 Посмотреть сообщение
Почему возникает ошибка при попытке создания explicit instantation? Я что-то не так делаю?
Explicit instantiation должна выполняться в том же самом namespace, в котором определен основной шаблон. Никакого explicit instantiation локально внутри функции не допускается.
0
02.06.2019, 19:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.06.2019, 19:29
Помогаю со студенческими работами здесь

Ошибка компиляции: template-id does not match any template declaration
Здравствуйте. Помогите, пожалуйста: #include &lt;iostream&gt; using namespace std; template...

Visual Studio выдаёт ошибку при вынесении объявления функции с template в .h файл. Без template всё работает
Проект содержит три файла: Source.cpp, arrTreat.h, arrTreat.cpp. Source.cpp: #include...

MSVC и template template classes
Приветствую. Как в MSVC передать template template класс? Простой пример ...

Friend template class with template class argument
Помогите подружить 2 класса: Имеется класс Student: template &lt;class _T&gt; class Faculty; class...


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

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