Библиотека knigago >> Компьютеры: Языки и системы программирования >> C, C++, C# >> C++. Сборник рецептов


СЛУЧАЙНЫЙ КОММЕНТАРИЙ

# 914, книга: Как полюбить зверя
автор: Мотя Губина

"Как полюбить зверя" от автора "Мотя Губина" - это захватывающая любовная фантастика, которая погружает читателей в мир магии, приключений и зарождающегося чувства. Главная героиня Айрин - студентка магической школы с сильным характером и неординарным талантом к магии. Ее жизнь переворачивается с ног на голову, когда она обнаруживает, что за ней охотится таинственный зверь. Волею судеб Айрин оказывается втянутой в смертельно опасное приключение вместе с загадочным демоном...

СЛУЧАЙНАЯ КНИГА

Креативность. Игорь Михайлович Намаконов
- Креативность

Жанр: О бизнесе популярно

Год издания: 2019

Серия: 4К – навыки будущего

Д Райан Стефенс , Кристофер Диггинс , Джонатан Турканис , Джефф Когсуэлл - C++. Сборник рецептов

C++. Сборник рецептов
Книга - C++. Сборник рецептов.  Д Райан Стефенс , Кристофер Диггинс , Джонатан Турканис , Джефф Когсуэлл  - прочитать полностью в библиотеке КнигаГо
Название:
C++. Сборник рецептов
Д Райан Стефенс , Кристофер Диггинс , Джонатан Турканис , Джефф Когсуэлл

Жанр:

Современные российские издания, Литература ХXI века (эпоха Глобализации экономики), Программирование: прочее, C, C++, C#

Изадано в серии:

неизвестно

Издательство:

КУДИЦ-ПРЕСС

Год издания:

ISBN:

5-91136-030-6

Отзывы:

Комментировать

Рейтинг:

Поделись книгой с друзьями!

Помощь сайту: донат на оплату сервера

Краткое содержание книги "C++. Сборник рецептов"

Данная книга написана экспертами по C++ и содержит готовые рецепты решения каждодневных задач для программистов на С++. Один из авторов является создателем библиотеки Boost Iostreams и нескольких других библиотек C++ с открытым исходным кодом. В книге затрагивается множество тем, вот лишь некоторые из них: работа с датой и временем; потоковый ввод/вывод; обработка исключений; работа с классами и объектами; сборка приложений; синтаксический анализ XML-документов; программирование математических задач. Читатель сможет использовать готовые решения, а сэкономленное время и усилия направить на решение конкретных задач.

Читаем онлайн "C++. Сборник рецептов". [Страница - 234]

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

Перегрузка операторов сдвига потоков влево и вправо (<< и >>) также требует применения операторов не-членов. Например, для записи нового объекта в поток, используя сдвиг влево, вам придется следующим образом объявить 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, может оказаться неожиданным.

Пример 15.7. Применение перегруженного оператора запятой, когда порядок вычисления аргументов не определен

int prompt_user() {

 cout << "give me an integer ... ";

 cin >> n;

 return n;

}


void f() {

 vector<int> v;

 // Следующий оператор может инициализировать v в неправильной

 // последовательности

 intialize(v) = prompt_user(), prompt_user();

--">

Оставить комментарий:


Ваш e-mail является приватным и не будет опубликован в комментарии.