c++ - 用作一维的多维 vector 的迭代器?

标签 c++ c++11 vector iterator std

我有一个看起来像这样的 vector :

std::vector<std::vector<MyClass>> myVector;

我想通过迭代器访问它的元素,就好像它是一个一维 vector 一样:

for (auto& x : myVector)
{
     foo(x); // x is an object of type MyClass
}

(即存在多个维度的事实对循环 myVector 的人来说是透明的)

我知道应该如何做到这一点,有一个自定义迭代器实现来保存当前索引,这样当其中一个 vector 没有更多元素时,它会重置一个索引并递增另一个索引,以便它可以开始遍历下一个 vector 等等。但我一直在尝试对这个想法进行编码,但似乎无法让它发挥作用。有谁知道我怎么可能做到这一点?或者更好的是,是否有任何具有类似实现的开源项目?

谢谢。

最佳答案

完全可以定义自己的迭代器来隐藏遍历 vector of vector 的所有细节,我写了一些代码来给你这个想法,注意它应该需要更多的检查,但它基本上可以工作并给你这个想法.

您只需编写所需的操作,使其在其他代码中像不透明的迭代器一样工作。

template <typename T>
struct vector2d
{
public:
  class iterator
  {
  public:
    using vector_type = std::vector<std::vector<T>>;
    using first_level_iterator = typename std::vector<std::vector<T>>::iterator;
    using second_level_iterator = typename std::vector<T>::iterator;

  private:
    vector_type& data;
    first_level_iterator fit;
    second_level_iterator sit;

  public:
    iterator(vector_type& data, bool begin) : data(data)
    {
      if (begin)
      {
        fit = data.begin();
        sit = fit->begin();
      }
      else
      {
        fit = data.end();
      }
    }

    inline bool operator!=(const iterator& other) const { return fit != other.fit || (fit != data.end() && sit != other.sit); }
    inline const iterator& operator++() {
      // don't go past end
      if (fit == data.end())
        return *this;

      // increment inner iterator
        ++sit;

      // if we reached the end of inner vector
      if (sit == fit->end())
      {
        // go to next vector
        ++fit;

        // if we reached end then don't reset sit since it would be UB
        if (fit != data.end())
        sit = fit->begin();
      }

      return *this;
    }

    T& operator*() const { return *sit; }
  };

public:
  std::vector<std::vector<T>> data;

  iterator begin() { return iterator(this->data, true); }
  iterator end() { return iterator(this->data, false); }
};

一个小测试:

int main() {
  vector2d<int> data;

  data.data.push_back(vector<int>());
  data.data.push_back(vector<int>());
  data.data.push_back(vector<int>());

  for (int i = 1; i < 5; ++i)
  {
    data.data[0].push_back(i);
    data.data[1].push_back(i*2);
    data.data[2].push_back(i*3);
  }

  for (auto i : data)
  {
    cout << i << endl;
  }

  return 0;
}

行为相当简单,但您必须确保它在所有边缘情况下始终保持一致。

关于c++ - 用作一维的多维 vector 的迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37871301/

相关文章:

c++ - findContours在opencv中找不到轮廓

c++ - MyType 允许 std::atomic<MyType> 的确切要求是什么?

c++ - 从映射值中的 unique_ptr 迭代原始指针

java - 如何访问多维 vector 中的元素?

c++ - 从 vector 中删除元素 – rbegin() 与 begin()

c++ - 在 Qt 中将 quint32 转换为字符串

c++ - 有没有办法将标准输出设置为二进制模式?

基于 C++ 堆栈的构造函数/析构函数未按预期工作

c++ - std::set 具有相同键和不同比较器的迭代器

c++ - 模板结构的 vector