C ++ итератор гетерогенных типов итераторов

0

У меня есть структура, которая содержит векторы разных типов. Я хотел бы создать один итератор, который будет перебирать каждый элемент каждого вектора и в соответствии с конкретными правилами предоставлять конкретное значение с помощью оператора *. Я уже создал игрушечный пример для итератора итераторов:

/*--------------------------------------------------------------------*/
/*  Copyright (C) Inria 2014

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 *  Project:    MixtComp
 *  Created on: Feb 20, 2014
 *  Author:     Vincent KUBICKI <[email protected]>
 **/

#include <iostream>
#include <iterator>
#include <vector>

class MyIterator : public std::iterator<std::input_iterator_tag, int>
{
  typedef std::vector<int>::const_iterator it   ;
  typedef std::vector<it>                  vecit;
  typedef std::vector<it>::iterator        itit ;
public:
  MyIterator(it itA ,
             it itB ,
             it endA,
             it endB)
  {
    vec_it_.push_back(itA);
    vec_it_.push_back(itB);
    vec_end_.push_back(endA);
    vec_end_.push_back(endB);

    it_vec_it_ = vec_it_.begin();
    it_vec_end_ = vec_end_.begin();
    if (itA == endA)
    {
      ++it_vec_it_;
      ++it_vec_end_;
    }
  }

  MyIterator(const MyIterator& mit) :
    vec_it_(mit.vec_it_),
    vec_end_(mit.vec_end_),
    it_vec_it_(mit.it_vec_it_),
    it_vec_end_(mit.it_vec_end_)
  {}

  MyIterator& operator++()
  {
    if (*it_vec_it_ != *it_vec_end_)
    {
      ++(*it_vec_it_);
      if (*it_vec_it_ == *it_vec_end_)
      {
        ++it_vec_it_;
        ++it_vec_end_;
      }
    }
    return *this;
  }

  MyIterator operator++(int)
  {
    MyIterator tmp(*this);
    operator++();
    return tmp;
  }

  bool operator==(const MyIterator& rhs)
  {
    return (*it_vec_it_ == *(rhs.it_vec_it_));
  }

  bool operator!=(const MyIterator& rhs)
  {
    return (*it_vec_it_ != *(rhs.it_vec_it_));
  }

  const int operator*()
  {
    return *(*it_vec_it_);
  }

private:
  vecit vec_it_; // vector of current iterators
  vecit vec_end_; // vector of end iterators

  itit it_vec_it_; // iterator on vec_it_
  itit it_vec_end_; // iterator on vec_end_
};

int main () {
  std::vector<int> dataA {1, 3, 4, 9};
  std::vector<int> dataB {11, 34, 43};

  MyIterator from(dataA.begin(),
                  dataB.begin(),
                  dataA.end(),
                  dataB.end());
  MyIterator until(dataA.end(),
                   dataB.end(),
                   dataA.end(),
                   dataB.end());

  for (MyIterator it = from; it != until; ++it)
  {
    std::cout << *it << std::endl;
  }
  return 0;
}

Однако в этой реализации оба dataA и dataB являются векторами того же типа. Предположим, что я хотел бы иметь разные типы векторов, например std::vector<std::pair<int, int>> и std::vector<std::pair<int, std::vector<int>>>.

Есть ли разумный (и простой) способ достичь этого?

Мои первые мысли заключались в замене it типа комбинацией Base и Derived итераторов. itit будет итератором на std::vector<Base>. Чтобы сравнить Base итераторы, я бы использовал указатели void для сравнения адресов их соответствующих объектов, указывающих на объект. operator*() будет определяться в классах Derived и будет обеспечивать одинаковый результат, например int.

  • 0
    У вас есть общий базовый класс, из которого происходят все типы? В противном случае вы потеряете информацию о типе. Тогда, повышение :: любой может быть вариант
  • 2
    Вы также можете посмотреть на boost::variant .
Показать ещё 1 комментарий
Теги:
iterator
vector
stl
standard-library

1 ответ

0

Мы сделаем замену itit структурой switch/case. Целое число, таким образом, Виль отслеживать "текущий" it объект.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню