为Matrix类设计迭代器

时间:2014-03-18 12:57:09

标签: c++ c++11 vector matrix iterator

我正在创建一个Matrix<T>课程。在为它实现迭代器时,我偶然发现了一个设计难题。

在内部,矩阵将数据保存在std::vector<T>(行主要)中 迭代矩阵的一种方法是使用双迭代器(嵌套)(由row_double模板参数指定):

for (auto it_i = mat.Begin<row_double>(); it_i < mat.End<row_double>(); ++it_i) {
  for (auto it_j = it_i->Begin(); it_j < it_i->End(); ++it_j) {
    cout << *it_j << " ";
  }
  cout << endl;    
}

第一个迭代器Matrix<T>::Iterator<row_double>

  • 遍历矩阵的行
  • RowProxy成员
  • 取消引用它会返回RowProxy

RowProxy通过std::vector<T>::iteratorBegin()等方法返回End()个迭代器。

我的想法是让RowProxy知道行的开头和行的大小(矩阵列的数量)。

问题RowProxy保存行引用开头的方式:

  • 我的第一个方法是将行的开头设为std::vector<T>::iterator 问题是在Visual Studio中,迭代器知道向量,并且对迭代器算术进行了调试检查。在构造ReverseEnd迭代器(对于第一行之前的行)时抛出错误:在num_columns开始之前,行的开头是vector 请注意,这与解除引用无关(whitch是UB)。我无法创建迭代器。

  • 我的第二种方法是使行的开头成为原始指针T *
    这里的问题是LineProxy需要返回std::vector<T>::iterator(通过它自己的Begin等)而我不能(不知道如何)构建{来自std::vector<T>::iterator的{​​1}}标准方式。 (没有找到任何特定于T *的引用,只是迭代器概念。在Visual Studio中似乎有一个构造函数std::vector<T>::iterator,在gcc a (T *, std::vector<T> *)中,两个都没有在其他编译器。)

我现在看到的解决方案是让我自己的迭代器与(T *)相同,但是谁不与任何std::vector<T>::iterator绑定,并且可以从vector构建并生成{ {1}}返回。但这真的好像重新发明轮子。

由于这是库的一部分(并且代码驻留在头文件中),编译器选项是不可能的(包括控制编译器选项的宏,因为它们会修改包含头的程序的整个行为,而不仅仅是库代码的行为)。解决方案也必须符合标准。语言为T *

1 个答案:

答案 0 :(得分:-3)

如上所述,最简单的方法是使用Eigen,它实际上是一个非常好的包。接下来最简单的事情就是在您的类中存储大小信息,然后您可以通过非常好的方式从矩阵中获取特定元素。只需编写一个返回vector [i + j * rowlength]的(i,j)运算符。迭代器应该可以很好地在一个循环中循环遍历整个向量,不确定它在两个循环中有多大意义。