|  | 
|      | 
|  | 
| 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 | ||||||||||||||||||||||||||||