os << "store " << get<0>(store) << " sales: "
<< accumulate(get<1>(store), get<2>(store),
Sales_data(s))
<< endl;
}
}
Цикл while последовательно читает поток istream по имени in, чтобы запустить обработку следующей книги. Вызов функции findBook() позволяет выяснить, присутствует ли строка s, и присваивает результаты вектору trans. Чтобы упростить написание типа trans, являющегося вектором кортежей, используем ключевое слово auto.
Если вектор trans пуст, значит, по книге s никаких продаж не было. В таком случае выводится сообщение и происходит возврат к циклу while, чтобы обработать следующую книгу.
Цикл for свяжет ссылку store с каждым элементом вектора trans. Поскольку изменять элементы вектора trans не нужно, объявим ссылку store ссылкой на константу. Для вывода результатов используем get: get<0> — индекс соответствующего магазина; get<1> — итератор на первую транзакцию; get<2> — на следующую после последней.
Поскольку класс Sales_data определяет оператор суммы (см. раздел 14.3), для суммирования транзакций можно использовать библиотечный алгоритм accumulate() (см. раздел 10.2.1). Как отправную точку суммирования используем объект класса Sales_data, инициализированный конструктором Sales_data(), получающим строку (см. раздел 7.1.4). Этот конструктор инициализирует переменную-член bookNo переданной строкой, а переменные-члены units_sold и revenue — нулем.
Упражнение 17.4. Напишите и проверьте собственную версию функции findBook().
Упражнение 17.5. Перепишите функцию findBook() так, чтобы она возвращала пару, содержащую индекс и пару итераторов.
Упражнение 17.6. Перепишите функцию findBook() так, чтобы она не использовала кортеж или пару.
Упражнение 17.7. Объясните, какую версию функции findBook() вы предпочитаете и почему.
Упражнение 17.8. Что будет, если в качестве третьего параметра алгоритма accumulate() в последнем примере кода этого раздела передать объект класса Sales_data?
17.2. Тип bitset
В разделе 4.8 приводились встроенные операторы, рассматривающие целочисленный операнд как коллекцию битов. Для облегчения использования битовых операций и обеспечения возможности работы с коллекциями битов, размер которых больше самого длинного целочисленного типа, стандартная библиотека определяет класс bitset (набор битов). Класс bitset определен в заголовке bitset.
17.2.1. Определение и инициализация наборов битов
Список конструкторов типа bitset приведен в табл. 17.2. Тип bitset — это шаблон класса, который, подобно классу array, имеет фиксированный размер (см. раздел 3.3.6). При определении набора битов следует указать в угловых скобках количество битов, которые он будет содержать:
bitset<32> bitvec(1U); //
Размер должен быть указан константным выражением (см. раздел 2.4.4). Этот оператор определяет набор битов bitvec, содержащий 32 бита. Подобно элементам вектора, биты в наборе битов не имеют имен. Доступ к ним осуществляется по позиции. Нумерация битов начинается с 0. Таким образом, биты набора bitvec пронумерованы от 0 до 31. Биты, расположенные ближе к началу (к 0), называются
Таблица 17.2. Способы инициализации набора битов