【问题标题】:Designing iterators for a Matrix class为 Matrix 类设计迭代器
【发布时间】:2014-04-24 04:15:08
【问题描述】:

我正在创建一个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&lt;T&gt;::Iterator&lt;row_double&gt;

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

RowProxy 通过Begin()End() 等方法返回std::vector&lt;T&gt;::iterator 迭代器。

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

问题RowProxy如何保持行引用的开头:

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

  • 我的第二种方法是将行首设为原始指针T *
    这里的问题是LineProxy 需要返回std::vector&lt;T&gt;::iterator(通过它自己的Begin 等),而我不能(不知道如何)以标准方式从T * 构造std::vector&lt;T&gt;::iterator。 (没有找到任何特定于std::vector&lt;T&gt;::iterator 的参考,只有迭代器概念。在Visual Studio 中似乎有一个构造函数(T *, std::vector&lt;T&gt; *),在gcc 中是(T *),两者都不能在另一个编译器中工作)。

我现在看到的解决方案是使我自己的迭代器与std::vector&lt;T&gt;::iterator 相同,但没有绑定到任何vector 并且可以从T * 构造并让RowProxy 返回它。但这似乎真的是在重新发明轮子。

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

【问题讨论】:

  • 当您可以简单地使用Eigen 时,为什么要实现自己的矩阵类。他们很久以前就解决了这一切:)
  • @Wilbert 自学练习,我打算在任务分配中使用我自己的实现。
  • 我不明白您建议的 for 循环语法如何方便或高效。无论如何,由于没有标准迭代器具有您的Matrix&lt;T&gt;::Iterator&lt;row_double&gt; 的行为,您应该自己设计它。我建议您查看std::valarray 的迭代器以获取想法。另请查看std::slice
  • Matrix&lt;T&gt;::Iterator&lt;row_double&gt; 已实现。 RowProxy 返回的嵌套迭代器现在只是 std::vector&lt;T&gt;::iterator

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


【解决方案1】:

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

【讨论】:

  • 我有。我有在单个循环中工作的迭代器。我有一个At(i, j),我有m[i][j](通过代理)。我想知道处理提到的具体问题的最佳方法..
猜你喜欢
  • 2014-04-16
  • 2015-09-30
  • 2014-12-19
  • 1970-01-01
  • 2011-03-20
  • 2012-12-15
  • 2019-11-27
  • 2015-05-17
  • 2021-01-19
相关资源
最近更新 更多