![]() |
![]() ![]() ![]() ![]() |
![]() |
Zip IteratorBoost , ,
| ||||||||||||||||||||||||||||||||||||
| Author: | Дэвид Абрахамс, Томас Беккер | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Contact: | ссылкачленzip_iteratorявляется типом кортежа, изготовленного из эталонных типов типов итераторов вИтераторАргументация.
difference_typeЧленzip_iteratorявляетсяdifference_typeпервого из типов итераторов вИтераторДвойнойаргумент. iterator_categoryчленzip_iteratorявляется конвертируемым к минимуму поперечных категорий типов итераторов вИтератораргумент. Например, еслиzip_iteratorсодержит только векторные итераторы, тоiterator_categoryконвертируется вboost::random_access_traversal_tag. Если добавить итератор списка, тоiterator_categoryбудет конвертируем вboost::bidirectional_traversal_tag, но уже не вboost::random_access_traversal_tag. zip_iterator requirementsВсе типы итераторов в аргументеИтераторТуплдолжен быть считываемым итератором модели. zip_iterator modelsВ результатеzip_iteratorмодели Readable Iterator. Тот факт, чтоzip_iteratorмодели только Readable Iterator, не мешает вам изменять значения, на которые указывают отдельные итераторы. Кортеж, возвращаемый операторомzip_iterator's, представляет собой кортеж, построенный из эталонных типов отдельных итераторов, а не их типов значений. Например, еслиzip_itявляетсяzip_iterator, первый член-итератор которого являетсяstd::vector zip_it->get<0>() = 42.0; Рассмотрим набор стандартных концепций обхода, полученных путем взятия наиболее утонченной стандартной концепции обхода, смоделированной каждым отдельным типом итератора в.ИтераторТупларгумент.zip_iteratorмоделирует наименее совершенную стандартную концепцию обхода в этом наборе. zip_iterator zip_iterator operationsВ дополнение к операциям, требуемым концепциями, смоделированнымиzip_iterator,zip_iterator, предусмотрены следующие операции. zip_iterator();
zip_iterator(IteratorTupleiterator_tuple);
template<typename OtherIteratorTuple>
zip_iterator(
const zip_iterator<OtherIteratorTuple>& other
, typename enable_if_convertible<
OtherIteratorTuple
, IteratorTuple>::type* = 0 // exposition only
);
constIteratorTuple&get_iterator_tuple()const;
ссылкаоператор*()const;
zip_iterator&оператор++();
zip_iterator &operator--();
template<typename IteratorTuple> zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t);
template<typename IteratorTuple> zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t);
ExamplesСуществует два основных типа приложенийzip_iterator. Первый касается эффективности выполнения: Если у вас есть несколько контролируемых последовательностей одинаковой длины, которые должны быть каким-то образом обработаны, например, алгоритмомдля, то более эффективно выполнять только одну параллельную итерацию, а не несколько отдельных итераций. Например, предположим, чтоvect_of_doublesиvect_of_intsявляются двумя векторами одинаковой длины, содержащими двойники и инты, соответственно, и рассмотрим следующие две итерации: std::vector<double>::const_iterator beg1 = vect_of_doubles.begin(); std::vector<double>::const_iterator end1 = vect_of_doubles.end(); std::vector<int>::const_iterator beg2 = vect_of_ints.begin(); std::vector<int>::const_iterator end2 = vect_of_ints.end(); std::for_each(beg1, end1, func_0()); std::for_each(beg2, end2, func_1()); Эти две итерации теперь могут быть заменены одной следующей:
std::for_each(
boost::make_zip_iterator(
boost::make_tuple(beg1, beg2)
),
boost::make_zip_iterator(
boost::make_tuple(end1, end2)
),
zip_func()
);
Необычная реализацияzip_funcможет выглядеть следующим образом:
struct zip_func :
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
{
void operator()(const boost::tuple<const double&, const int&>& t) const
{
m_f0(t.get<0>());
m_f1(t.get<1>());
}
private:
func_0 m_f0;
func_1 m_f1;
};
Второе важное применение zip_iteratorявляется строительным блоком для создания комбинированных итераторов. Комбинирующий итератор представляет собой итератор, который параллелен-итерирует несколько контролируемых последовательностей и, при снятии ссылок, возвращает результат применения функтора к значениям последовательностей в соответствующих положениях. Это может быть достигнуто с помощьюzip_iteratorв сочетании сTransform_iterator. Предположим, например, что у вас есть два вектора двойников, скажемvect_1иvect_2, и вам нужно подвергнуть клиента контролируемой последовательности, содержащей продукты элементовvect_1иvect_2. Вместо того, чтобы размещать эти продукты в третьем векторе, вы можете использовать комбинированный итератор, который вычисляет продукты на лету. Предположим, чтоtuple_multipliesявляется функтором, который работает какstd::multiplies, за исключением того, что он принимает свои два аргумента, упакованные в кортеж. Затем два итератораit_beginиit_end, определенные ниже, определяют контролируемую последовательность, содержащую продукты элементовvect_1иvect_2:
typedef boost::tuple<
std::vector<double>::const_iterator,
std::vector<double>::const_iterator
> the_iterator_tuple;
typedef boost::zip_iterator<
the_iterator_tuple
> the_zip_iterator;
typedef boost::transform_iterator<
tuple_multiplies<double>,
the_zip_iterator
> the_transform_iterator;
the_transform_iterator it_begin(
the_zip_iterator(
the_iterator_tuple(
vect_1.begin(),
vect_2.begin()
)
),
tuple_multiplies<double>()
);
the_transform_iterator it_end(
the_zip_iterator(
the_iterator_tuple(
vect_1.end(),
vect_2.end()
)
),
tuple_multiplies<double>()
);
Статья Zip Iterator раздела может быть полезна для разработчиков на c++ и boost. :: Главная :: ::
|
|||||||||||||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 | ||||||||||||||||||||||||||||