![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
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 |