设计迭代的Matrix类(Designing iterators for a Matrix clas

2019-10-19 15:14发布

我创建一个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>::iterator经由方法迭代喜欢Begin()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>::iteratorT *标准方式。 (没有找到特定于任何参考std::vector<T>::iterator ,只是迭代器概念。在Visual Studio中似乎有一个构造(T *, std::vector<T> *)在一个GCC (T *)没有一个在其他编译器的工作原理)。

我现在看到的解决方案是让我自己的迭代器具有相同std::vector<T>::iterator ,但谁不绑定到任何vector ,可以从构造T * ,并RowProxy返回。 但是,这真的好像重新发明轮子。

由于这是一个库的一部分(和代码驻留在头),编译器选项都出了问题(包括控制编译器选项,因为他们修改包括头,不只是的行为程序的整个行为宏库代码)。 另外,解决方案必须是符合标准的。 该语言是C++11

Answer 1:

要做到这一点,作为上述简单的方法是用艾根,它真的是一个非常漂亮的包装。 这样做将大小信息存储在您的课下一个最简单的事情,那么你必须得到一个特定的元素你的矩阵的一个非常好的方式。 只写第(i,j)的操作者,返回向量[I + J * rowlength]。 迭代器应该在一个循环遍历整个矢量工作得很好,不知道有多少意义上讲,它让遍历两种。



文章来源: Designing iterators for a Matrix class