Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/29: Рейтинг темы: голосов - 29, средняя оценка - 4.93
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
1

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)

07.10.2015, 15:04. Показов 5637. Ответов 32
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не плодить много тем, корни у которых одни, решил создать эту тему.

Дошел до места. Параметры шаблонов функций, не являющиеся типами.
Там описан такого вида пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
#include <algorithm>
 
template <typename T, int VAL>
T addValue(T const& x){
   return x+VAL;
}
 
int main()
{
     vector<int> v1(100);
     vector<int> v2(100);
     transform(v1.begin(), v1.end(),v2.begin(),addValue<int,5>);
}
Дальше авторы уточняют о проблеме, которая проявляется в этом примере.
Заметим, что в этом примере проявляется следующая проблема: addValue<int, 5> — это шаблон функции, который интерпретируется как имя семейства перегруженных функций (даже если это семейство состоит всего из одного элемента).
Я вообще авторов не понял. Просьба прояснить этот туманный момент.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.10.2015, 15:04
Ответы с готовыми решениями:

Использование обобщенных лямбда-выражений с SFINAE из книги "Шаблоны C++. Справочник разработчика"
(перевод)...

Шаблоны C++: справочник разработчика
Нашёл книжку в интернете. Прочитал несколько глав в электронном виде. И теперь хочу купить себе...

Хранить шаблоны документов в базе и выводить данные в эти шаблоны
Доброго времени суток. Интересует вопрос: мне необходимо формировать вордовские документы по...

Чем отличаются шаблоны HTML и шаблоны WordPress
В чём различие между шаблонами HTML и WordPress. Кроме того, что создаются они разными способами....

32
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
10.10.2015, 21:59 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от daslex Посмотреть сообщение
template <typename T2>
* * T& operator = (T2 &) ;
ваш оператор возвращает тип T& а вовсе не тип агрегата:
template <typename T>class MyClass

Цитата Сообщение от daslex Посмотреть сообщение
return *this; * /* <----- Вот здесь застрял. */
результат выражения *this
имеет тип: MyClass<T>&
а вовсе не T&

лекарство:

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
 
using namespace std;
 
template <typename T>
class MyClass{
    T value;
public:
    
    // --- ошибка №1
    // вы не соблюдаете граммар const
    
    
    // геттеры должны быть двух видов: 
    // константная и не константная версии
    // и возвращают они по ссылке, что бы избежать
    // избыточного копирования при возврате по значению
    const T& get_value()const { return this->value; }
    
    // пример иллюстрация того,
    // как можно вывести неконстантную версию геттера
    // из константной.
    // это делается для того, что бы в случае изменений в логике геттера
    // можно было вносить изменения только в одном месте: в константной версии
    T& get_value() 
    { 
        return const_cast<T&>(
            const_cast<const MyClass*>(this)->get_value()
        );
    }
    
    // обратите внимание на использование универсальной ссылке
    // один шаблоно-сеттер позволяет реализовать 
    // стратегию оптимальной передачи аргументов любого типа
    // лишь бы он был совместим с типом приемника данных T
    template<class U> void set_value(const U&& x) 
        { this->value = std::forward<U>(x); }
    
 
    MyClass(const T&x)
        :value(x) 
    {}
    MyClass(T&&x)
        :value( std::forward<T>(x) )
    {}
 
    // --- вынесем туловище шаблона-функции-члена за пределы класса
    // что бы проиллюстрировать синтаксис
    template <typename U>
    const MyClass& operator= (const MyClass<U>&);
    
 
    // --- не забудем реализовать move-operator
    // что бы оптимизировать операцию присвоения для T
    // умеющих move семантику
    template <typename U>
    const MyClass& operator= (const MyClass<U>&& rhs)
        { this->value = std::move(rhs.get_value()); }
 
    // ВАЖНО: обратие внимание: 
    // операторы присвоения принимают нечто либо по константной ссылке,
    // либо по универсальной, 
    // либо r-value-reference
    // а возвращается всегда const-reference на *this класса
    
    // если вы будете соблюдать эту каноническую согласно граммар-const конструкцию
    // для оператора присвоения,
    // то это привентивно оградит вас от "непонятных" ошибок в шаблонах.
};
 
 
template <typename T>
   template <typename U>
        const MyClass<T>& MyClass<T>::operator= (const MyClass<U>& rhs) {
            this->value = rhs.get_value(); 
            return *this;   
        }
 
 
int main(){
    MyClass<int>    Num1(20);
    MyClass<double> Num3(3.14);
    Num3 = Num1; 
}
1
7787 / 6555 / 2983
Регистрация: 14.04.2014
Сообщений: 28,633
10.10.2015, 22:05 22
Цитата Сообщение от hoggy Посмотреть сообщение
а возвращается всегда const-reference на *this класса
Почему всегда const?
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
10.10.2015, 22:21  [ТС] 23
Спасибо. Невнимательность, однако. ответ hoggy еще до описания лекарства прекрасно мне помог. А ответ nmcf, хорошо этому поспособствовал.

Добавлено через 14 минут
Цитата Сообщение от hoggy Посмотреть сообщение
// --- ошибка №1
в данной ситуации, это не столько ошибка, сколько я до этого еще не дошел. У Вас, например, в лекарстве превалируют r-value ссылки, я о них только поверхностно знаю, а в самих константах недостаточно ориентируюсь и иногда их опускаю, чтобы они меньше отвлекали внимания. Не буду отрицать, что иногда о них забываю, но сейчас даже если бы и забыл где-то, я их просто для себя пропустил.

Даже если Ваш пример-лекарство действительно хороший, я сейчас(в эти минуты) на очень ранней стадии, чтобы его восприять.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
10.10.2015, 22:46 24
Цитата Сообщение от nmcf Посмотреть сообщение
Почему всегда const?
принцип максимального ограничения возможностей
при сохранении необходимой функциональности.

в частности, нельзя написать всякую ересь, которая противоречит здравому смыслу.
наподобие:

C++
1
2
3
4
5
6
7
8
9
10
struct bad
{
    bad& operator=(const bad&) { return *this; }
};
 
int main()
{
    bad b1, b2, b3;
    (b1 = b2) = b3;
}
Добавлено через 5 минут
Цитата Сообщение от daslex Посмотреть сообщение
превалируют r-value ссылки, я о них только поверхностно знаю
да ну и забейте покамест на них.
они не сложны - приложаццо.

однако в любом случае, когда пишите шаблоно-прототип,
всегда задавайте себе вопросы:
как именно будет осуществляться передача аргументов?
не будет ли здесь избыточного копирования аргументов?

всегда задавайте себе вопрос:
меняет ли функция-член логическое/константное состояние экземпляра класса?
если ответ: нет, не меняет, то метод должен быть const.

всегда задавайте себе вопрос:
меняет ли функция-член состояние входного аргумента?
если ответ: нет, не меняет, то аргумент должен быть const.

придерживайтесь этих простых правил,
и они позволят вам избежать "портянок " ошибок компиляции,
связанных с нарушением контрактов классов,
при подстановке конкретного T
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
20.10.2015, 09:10  [ТС] 25
Опять я отписываю в этой теме. Вопрос не по книге, но по шаблонам. Он мог бы быть в книге, но до С++11 было еще очень далеко.

Я понять не могу почему
C++
1
2
3
4
5
6
//корректно
template <int x=0>
int (&foo())[x][x]{
   int Arr[5][6];
   return Arr;
}
C++
1
2
3
4
5
//Некорректно
int (&foo())[5][5]{ // <---- как бы [X][X] ,(X==X)
   int Arr[5][6];
   return Arr;
}
Я мог бы предположить, что рождается огромная масса, очень большое семейство функций, но я в этом очень сомневаюсь. И понять не могу чего происходит. Как это так?
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.10.2015, 09:24 26
Цитата Сообщение от daslex Посмотреть сообщение
//корректно
оба примера не корректны
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
20.10.2015, 10:46  [ТС] 27
Поспорим?

Добавлено через 20 минут
Под корректно я имею ввилу успешную компиляцию'

Добавлено через 23 минуты
Я подозреваю, что шаблон создает 2 функции, одну с массивом [X][X] и вторую с массивом [][X]. Первая не подходит, вторая же подходит. Но может я неправильно думаю.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
20.10.2015, 11:48 28
Лучший ответ Сообщение было отмечено daslex как решение

Решение

Цитата Сообщение от daslex Посмотреть сообщение
Под корректно я имею ввилу успешную компиляцию'
Просто нет вызова, который потребовал бы инстанцирования шаблона. Добавь его, и будет ошибка несовместимости типов:
C++
1
foo<1>();
2
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
20.10.2015, 12:25  [ТС] 29
Всё. Этот момент уяснил. Благодарю.
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.10.2015, 22:16 30
Цитата Сообщение от daslex Посмотреть сообщение
Поспорим?
на ключи от машины, м?
0
daslex
20.10.2015, 22:39  [ТС]
  #31

Не по теме:

поезд ушел :p

0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
20.10.2015, 23:14 32
Цитата Сообщение от hoggy Посмотреть сообщение
// геттеры должны быть двух видов:
* * // константная и не константная версии
хм, это good practice такая? или есть строгий смысл?

Добавлено через 12 минут
Цитата Сообщение от hoggy Посмотреть сообщение
// пример иллюстрация того,
* * // как можно вывести неконстантную версию геттера
* * // из константной.
* * // это делается для того, что бы в случае изменений в логике геттера
* * // можно было вносить изменения только в одном месте: в константной версии
а... вижу
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.10.2015, 00:08 33
Цитата Сообщение от tapochka Посмотреть сообщение
хм, это good practice такая? или есть строгий смысл?
это хорошая практика в которой есть смысл
0
21.10.2015, 00:08
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.10.2015, 00:08
Помогаю со студенческими работами здесь

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1) количество элементов...

Не могу обнаружить ошибку в учебной программе из книги (шаблоны классов)
Вот упрощённый код учебной программы из книжки Детейла. Не компилится, пишет:...

Шаблоны
Я разбираюсь с ООП в С++ и застрял на шаблонах, будьте добры приведите пример кода, к примеру ...

шаблоны
доброго времени суток, форумчане. буд благодарен за помощь в таком вот задании: *** Написать...

Шаблоны
Написать шаблон функции для вычисления количества нулевых элементов в каждом столбце и каждой...

Шаблоны
Задание 1 . Создать класс типа сигнал, как шаблон, чтобы на его основе реализовать и двухбайтовые...


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

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