Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

s5 = String("ham ") + s2;

Компилятор позволяет вам немного сэкономить ваши действия и не вводить несколько символов за счет поиска и вызова соответствующего конструктора.

Перегрузка операторов сдвига потоков влево и вправо (

<<
и
>>
) также требует применения операторов не-членов. Например, для записи нового объекта в поток, используя сдвиг влево, вам придется следующим образом объявить
operator<<
:

ostream& operator<<(ostream& str, const MyClass& obj);

Конечно,

вы можете создать подкласс одного из классов потока стандартной библиотеки и добавить все необходимые вам операторы сдвига влево, но будет ли такое решение действительно удачным? При таком решении только тот программный код, который использует ваш новый класс потока, сможет записывать в него объекты вашего специального класса. Если вы используете независимый оператор, любой программный код в том же самом пространстве имен сможет без проблем записать ваш объект в
ostream
(или считать его из
istream
).

15.6. Инициализация последовательности значениями, разделяемыми запятыми

Проблема

Требуется инициализировать последовательность набором значений, разделяемых запятыми, подобно тому как это делается для встроенных массивов.

Решение

При инициализации стандартных последовательностей (таких как

vector
и
list
) можно использовать синтаксис с запятыми, определяя вспомогательный класс и перегружая оператор запятой, как это продемонстрировано в примере 15.6.

Пример 15.6. Вспомогательные классы для инициализации стандартных последовательностей с применением синтаксиса с запятыми

#include <vector>

#include <iostream>

#include <iterator>

#include <algorithm>

using namespace std;

template<class Seq_T>

struct comma helper {

 typedef typename Seq_T::value_type value_type;

 explicit comma_helper(Seq_T& x) : m(x) {}

 comma_helper& operator=(const value_type& x) {

m.clear;

return operator+=(x);

 }

 comma_helper& operator+=(const value_type& x) {

m.push_back(x);

return *this;

 }

 Seq_T& m;

};

template<typename Seq_T>

comma_helper<Seq_T> initialize(Seq_T& x) {

 return comma_helper<Seq_T>(x);

}

template<class Seq_T, class Scalar_T>

comma_helper<Seq_T>& operator,(comma_helper<Seq_T>& h, Scalar_T x) {

 h += x;

 return h;

}

int main {

 vector v;

 int a = 2;

 int b = 5;

 initialize(v) = 0, 1, 1, a, 3, b, 8, 13;

 cout << v[3] << endl; //
выдает 2

 system("pause");

 return EXIT_SUCCESS;

}

Обсуждение

Часто стандартные последовательности инициализируются путем вызова несколько раз функции-члена

push_back
. Поскольку это приходится делать не так уж редко, я написал функцию
initialize
, которая помогает избавиться от этого скучного занятия, позволяя выполнять инициализацию значениями, разделяемыми запятыми, подобно тому как это делается во встроенных массивах.

Возможно, вы и не знали, что запятая является оператором, который можно переопределять. Здесь вы не одиноки — этот факт не является общеизвестным. Оператор запятой было разрешено перегружать почти только ради решения этой задачи.

В решении используется вспомогательная функция

initialize
, которая возвращает шаблон вспомогательной функции
comma_helper
. Этот шаблон содержит ссылку на последовательность и перегруженные операторы
operator,
,
operator=
и
operator+=
.

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

v = 1, 1, 2, ...;
. Компилятор рассматривает
v = 1
как недопустимое подвыражение, потому что в стандартных последовательностях не поддерживается оператор присваивания единственного значения. Функция
initialize
конструирует соответствующий объект
comma_helper
, который может хранить последовательность, используемую в перегруженном операторе присваивания и запятой.

Оператор запятой (comma operator), называемый также оператором последовательности (sequencing operator), по умолчанию рассматривает выражения слева направо, и в результате получается значение и тип самого правого значения. Однако при перегрузке

operator
принимает новый смысл и теряет первоначальную семантику. Здесь возникает один тонкий момент — оценка параметров слева направо теперь не гарантируется, и результат выполнения программного кода, приведенного в примере 15.7, может оказаться неожиданным.

Поделиться:
Популярные книги

Начальник милиции. Книга 5

Дамиров Рафаэль
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 5

Папина дочка

Рам Янка
4. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Папина дочка

Возвышение Меркурия. Книга 8

Кронос Александр
8. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 8

АллатРа

Новых Анастасия
Научно-образовательная:
психология
история
философия
обществознание
физика
6.25
рейтинг книги
АллатРа

Золушка вне правил

Шах Ольга
Любовные романы:
любовно-фантастические романы
6.83
рейтинг книги
Золушка вне правил

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Барон Дубов 6

Карелин Сергей Витальевич
6. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов 6

Ротмистр Гордеев

Дашко Дмитрий Николаевич
1. Ротмистр Гордеев
Фантастика:
фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Лучше подавать холодным

Аберкромби Джо
4. Земной круг. Первый Закон
Фантастика:
фэнтези
8.45
рейтинг книги
Лучше подавать холодным

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12