两级迭代器 C++

计算科学 C++ 向量
2021-12-19 17:55:49

我正在尝试实现一个两级迭代器,正如我现在将描述的那样。基本上我有一个“向量向量”,我想要一个迭代器,它将遍历向量向量中的所有对象。

下面的代码做到了这一点,但它有点难看,我不能在 for 循环中声明迭代器。因此,我在 for 循环之前声明了迭代器,然后迭代,然后删除迭代器,这是 klugy。我不知道 C++,所以我在这里有点不合群,所以请不要犹豫,提供 C++ 编程建议。如何修复此代码,以便可以在 for 循环中声明迭代器?

// iterator_2.cpp
//to compile:   g++ iterator_2.cpp

#include <iostream>
#include <vector>

using namespace std;

typedef double Object;

typedef vector<Object> ObjectVector;
vector<ObjectVector*> types;

class ObjectIterator{
 protected:

 public:

 Object *object;
 ObjectIterator operator++()
  {object++; //increment object
    // when current object is at the end for type[s] increment s and set object to the first entry in the next type
    if(object==&(*(types[s])->end())){
      s++;
      object=&((*types[s])[0]);
    }
    return (*this);
  }

 ObjectIterator():null(0){s=0;object= &((*types[0])[0]);};

  int s;
  ObjectIterator *null;

};

int num_types=2;

int main(){

  int num_objects[num_types];
  num_objects[0]=3;
  num_objects[1]=5;

  // initialize objects for each type

  for(int s=0;s<num_types;s++){
    ObjectVector *objectlist = new ObjectVector;

    for(int i=0;i<num_objects[s];i++){
      objectlist->push_back((double)2*i*(s+1));
    }
    types.push_back(objectlist);
  }


// use the two-level iterator

  ObjectIterator *OI;
  OI = new ObjectIterator;

  for(; OI->s < num_types; ++(*OI))
    {
      cout << *(OI->object)<<endl;
    }
  delete OI;  

}
1个回答

虽然我没有说这是一个最佳实现或考虑到所有边缘情况的最佳实现,但下面是我为您的任务整理的示例实现,它可以让您了解如何解决您的问题。

头文件

#ifndef _container_hpp_
#define _container_hpp_

#include <vector>

class container {
public:
   class iterator {
   public:
       iterator();
       void operator++();
       double & operator*();
       bool operator==(const iterator & it);
       bool operator!=(const iterator & it);
   private:
       friend container;
       container * parent;
       int count;
       int r, c;
   };

   container();
   container(int rows, int cols);
   void resize(int rows, int cols);
   double & operator()(int r, int c);
   iterator begin();
   iterator end();

   int nrows() const;
   int ncols() const;

private:
    std::vector<std::vector<double>> data;
    int totalElements;
    int rows, cols;
};



#endif

实施文件

#include "Container.hpp"

container::iterator::iterator():parent(0),r(0),c(0) {

}
void container::iterator::operator++() {
    int totRows = parent->nrows();
    if( r != totRows ){
        int totCols = parent->ncols();
        if( c == (totCols-1) ){ c = 0; ++r; }
        else{ ++c; }
        ++count;
    }
}
double & container::iterator::operator*() {
    return parent->data[r][c];
}

bool container::iterator::operator==(const iterator & it) {
    return (parent == it.parent && count == it.count);
}
bool container::iterator::operator!=(const iterator & it) {
    return !this->operator==(it);
}

container::container():data(0),totalElements(0),rows(0),cols(0) {

}
container::container(int rows_, int cols_):data(rows_),totalElements(rows_*cols_),rows(rows_),cols(cols_) {
    for(int i = 0; i < rows; ++i ){
        data[i].resize(cols);
    }
}

void container::resize(int rows_, int cols_) {
    rows = rows_; cols = cols_;
    data.resize(rows);
    for(int i = 0; i < rows; ++i ){
        data[i].resize(cols);
    }
}
double & container::operator()(int r, int c) {
    return data[r][c];
}

container::iterator container::begin() {
    iterator it;
    it.parent = this;
    it.count = 0;
    it.r = 0;
    it.c = 0;
    return it;
}
container::iterator container::end() {
    iterator it;
    it.parent = this;
    it.count = totalElements;
    it.r = -1;
    it.c = -1;
    return it;
}

int container::nrows() const {
    return rows;
}
int container::ncols() const {
    return cols;
}

一个样本main.cpp

#include "Container.hpp"

int main( int argc, char** argv ){
    container test(2,2);
    for(int i = 0; i < test.nrows(); ++i ){
        for(int j = 0; j < test.ncols(); ++j ){
            test(i,j) = i + j;
        }
    }

    container::iterator it;
    for( it = test.begin(); it != test.end(); ++it ){
        printf("Value = %lf\n",*it);
    }


    return 0;
}

正如预期的那样,这将输出以下内容:

Value = 0.000000
Value = 1.000000
Value = 1.000000
Value = 2.000000

正如您可能知道的那样,它的实现遵循与 STL C++ 库关于迭代器的类似约定(至少在基本级别上)。