C++ 用作一维的多维向量的迭代器?

C++ 用作一维的多维向量的迭代器?,c++,c++11,vector,iterator,std,C++,C++11,Vector,Iterator,Std,我有一个向量,看起来像这样: std::vector<std::vector<MyClass>> myVector; (也就是说,存在多个维度的事实对于通过myVector循环的人来说是透明的) 我知道应该怎么做,有一个自定义的迭代器实现,它保存当前的索引,这样当一个向量没有更多的元素时,它会重置一个索引并增加另一个,这样它就可以开始遍历下一个向量,依此类推。但我一直在尝试编码这个想法,但似乎无法让它工作。有人知道我怎样才能做到这一点吗?或者更好,如果有任何开源项目有类

我有一个向量,看起来像这样:

std::vector<std::vector<MyClass>> myVector;
(也就是说,存在多个维度的事实对于通过myVector循环的人来说是透明的)

我知道应该怎么做,有一个自定义的迭代器实现,它保存当前的索引,这样当一个向量没有更多的元素时,它会重置一个索引并增加另一个,这样它就可以开始遍历下一个向量,依此类推。但我一直在尝试编码这个想法,但似乎无法让它工作。有人知道我怎样才能做到这一点吗?或者更好,如果有任何开源项目有类似的实现


谢谢。

完全可以定义自己的迭代器来隐藏遍历向量向量的所有细节,我编写了一些代码来告诉您这个想法,请注意,它需要更多的检查,但它基本上是有效的,并且给了您这个想法

您只需要编写所需的操作,就可以在其他代码(如不透明迭代器)中工作

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); }
};
模板
结构向量2D
{
公众:
类迭代器
{
公众:
使用vector_type=std::vector;
使用第一级迭代器=typename std::vector::iterator;
使用第二级迭代器=typename std::vector::iterator;
私人:
向量类型和数据;
第一级迭代器拟合;
第二层迭代器sit;
公众:
迭代器(向量类型&数据,布尔开始):数据(数据)
{
如果(开始)
{
fit=data.begin();
sit=fit->begin();
}
其他的
{
fit=data.end();
}
}
内联布尔运算符!=(常量迭代器和其他)常量{return fit!=other.fit | |(fit!=data.end()&&sit!=other.sit);}
内联常量迭代器和运算符++(){
//不要走到尽头
if(fit==data.end())
归还*这个;
//增量内迭代器
++坐;
//如果我们到达内向量的末端
如果(sit==fit->end())
{
//转到下一个向量
++适合;
//如果我们到达终点,那么不要重置坐姿,因为这将是UB
if(fit!=data.end())
sit=fit->begin();
}
归还*这个;
}
T&运算符*()常量{return*sit;}
};
公众:
std::矢量数据;
迭代器begin(){返回迭代器(this->data,true);}
迭代器end(){返回迭代器(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;
}
intmain(){
矢量二维数据;
data.data.push_back(vector());
data.data.push_back(vector());
data.data.push_back(vector());
对于(int i=1;i<5;++i)
{
data.data[0]。推回(i);
data.data[1]。推回(i*2);
data.data[2]。推回(i*3);
}
用于(自动i:数据)
{

cout完全可以定义自己的迭代器来隐藏遍历向量向量的所有细节,我写了一些代码来告诉你这个想法,记住它应该需要更多的检查,但它基本上是有效的,并且给了你这个想法

您只需要编写所需的操作,就可以在其他代码(如不透明迭代器)中工作

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); }
};
模板
结构向量2D
{
公众:
类迭代器
{
公众:
使用vector_type=std::vector;
使用第一级迭代器=typename std::vector::iterator;
使用第二级迭代器=typename std::vector::iterator;
私人:
向量类型和数据;
第一级迭代器拟合;
第二级迭代器sit;
公众:
迭代器(向量类型&数据,布尔开始):数据(数据)
{
如果(开始)
{
fit=data.begin();
sit=fit->begin();
}
其他的
{
fit=data.end();
}
}
内联布尔运算符!=(常量迭代器和其他)常量{return fit!=other.fit | |(fit!=data.end()&&sit!=other.sit);}
内联常量迭代器和运算符++(){
//不要走到尽头
if(fit==data.end())
归还*这个;
//增量内迭代器
++坐;
//如果我们到达内向量的末端
如果(sit==fit->end())
{
//转到下一个向量
++适合;
//如果我们到达终点,那么不要重置坐姿,因为这将是UB
if(fit!=data.end())
sit=fit->begin();
}
归还*这个;
}
T&运算符*()常量{return*sit;}
};
公众:
std::矢量数据;
迭代器begin(){返回迭代器(this->data,true);}
迭代器end(){返回迭代器(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;
}
intmain(){
矢量二维数据;
data.data.push_back(vector());
data.data.push_back(vector());
data.data.push_back(vector());
对于(int i=1;i<5;++i)
{
data.data[0]。推回(i);
data.data[1]。推回(i*2);
data.data[2]。推回(i*3);
}
用于(自动i:数据)
{

cout一个非常小的范围类型:

template<class It>
struct range_t {
private:
  It b, e;
public:
  It begin() const { return b; }
  It end() const { return e; }

  decltype(auto) front() const { return *b; }
  decltype(auto) back() const { return *std::prev(e); }

  bool empty() const { return b==e; }

  range_t without_front( std::size_t n = 1 ) const {
    auto r = *this;
    std::advance(r.b,n);
    return r;
  }      
  range_t without_back( std::size_t n = 1 ) const {
    auto r = *this;
    std::advance(r.e,std::ptrdiff_t(-n));
    return r;
  }      

  range_t(It s, It f):b(std::move(s)), e(std::move(f)) {}
  range_t():b(), e() {}
};
template<class It>
range_t<It> range( It b, It e ) {
  return {std::move(b), std::move(e)};
}
模板
结构范围{
私人:
它是b,e;
公众:
它的begin()常量{return b;}
It end()常量{return e;}
decltype(auto)front()常量{return*b;}
decltype(auto)back()常量{return*std::prev(e);}
bool empty()常量{返回b==e;}
不带前端的范围(标准::大小n=1)常数{
自动r=*这个;
标准:预付款(r.b,n);
返回r;
}      
没有返回的范围(标准::大小n=1)常数{
自动r=*这个;
std::advance(r.e,std::ptrdiff_t(-n));
返回r;
}      
范围t(It s,It f):b(std::move(s)),e(std::move(f)){
范围t():b(),e(){}
};
模板
范围\u t范围(It b、It e){
返回{std::move(b),std::move(e)};
}
使用范围执行此任务比使用迭代器容易得多

template<class Outer, class Inner>
struct stacked_range_t {
  range_t<Outer> outer;
  stacked_range_t()=default;
  stacked_range_t( range_t<Outer> o ):outer(std::move(o)) {}
  struct iterator {
  private:
    range_t<Outer> outer;
    range_t<Inner> inner;
  public:
    iterator(
      range_t<Outer> o,
      range_t<Inner> i
    ):outer(std::move(o)), inner(std::move(i)) {}
    iterator()=default;

    friend auto mytie(iterator const& it) {
      return std::tie( it.outer.begin(), it.inner.begin(), it.inner.end() );
    }
    friend bool operator==(iterator const& lhs, iterator const& rhs) {
      return mytie(lhs)==mytie(rhs);
    }
    friend bool operator!=(iterator const& lhs, iterator const& rhs) {
      return mytie(lhs)==mytie(rhs);
    }
    using difference_type = std::ptrdiff_t;
    using value_type = typename std::iterator_traits<Inner>::value_type;
    using pointer = typename std::iterator_traits<Inner>::pointer;
    using reference = typename std::iterator_traits<Inner>::reference;
    using iterator_category = std::input_iterator_tag;

    reference operator*() const {
      return *inner.begin();
    }
    pointer operator->() const {
      return inner.begin().operator->();
    }
    iterator& operator++() {
      using std::begin; using std::end;
      inner = inner.without_front();
      while (inner.empty())
      {
        outer = outer.without_front();
        if (!outer.empty())
          inner = range( begin(outer.front()), end(outer.front()) );
      }
      return *this;
    }
    iterator operator++(int) {
      auto it = *this;
      ++*this;
      return it;
    }
  };
  iterator end() const {
    return { range( outer.end(), outer.end() ), {} };
  }
  // a bit tricky:
  iterator begin() const {
    if (outer.empty()) return end();

    auto rout = outer;
    while( !rout.empty() ) {
      using std::begin; using std::end;
      auto rin = range( begin(rout.front()), end(rout.front()) );
      if (!rin.empty())
        return {std::move(rout), std::move(rin)};
      rout = rout.without_front();
    }
    return end();
  }
};
模板
结构堆叠\u范围\u t{
范围外;
堆叠的_范围_t()=默认值;
堆叠的范围:外部(std::move(o)){
结构迭代器{
私人:
范围外;
范围内;
公众:
迭代器(
射程,
射程
):外部(std::move(o)),内部(std::move(i)){}
迭代器()=默认值;
friend auto mytie(迭代器常量&it){
#include <stdio.h>
#include <vector>
template <typename V>
void f(V& v){
    for(auto& e : v){
        f(e);
    }
    printf("\n");
}

template <>
void f(int& v){
    printf("%d ",v);
}

int main(){
    std::vector<int> v1={1,2};
    f(v1);
    std::vector<std::vector<int> > v2={{3,4},{5,6,7}};
    f(v2);
    return 0;
};
for (auto& x : myVector | ranges::view::join)
{
     foo(x); // x is an object of type MyClass&
}