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
?
В разделе 4.8 приводились встроенные операторы, рассматривающие целочисленный операнд как коллекцию битов. Для облегчения использования битовых операций и обеспечения возможности работы с коллекциями битов, размер которых больше самого длинного целочисленного типа, стандартная библиотека определяет класс bitset
(набор битов). Класс bitset
определен в заголовке bitset
.
Список конструкторов типа bitset
приведен в табл. 17.2. Тип bitset
— это шаблон класса, который, подобно классу array
, имеет фиксированный размер (см. раздел 3.3.6). При определении набора битов следует указать в угловых скобках количество битов, которые он будет содержать:
bitset<32> bitvec(1U); //
Размер должен быть указан константным выражением (см. раздел 2.4.4). Этот оператор определяет набор битов bitvec
, содержащий 32 бита. Подобно элементам вектора, биты в наборе битов не имеют имен. Доступ к ним осуществляется по позиции. Нумерация битов начинается с 0. Таким образом, биты набора bitvec
пронумерованы от 0 до 31. Биты, расположенные ближе к началу (к 0), называются
Таблица 17.2. Способы инициализации набора битов