如何从 STL 类“继承”迭代器?

Posted

技术标签:

【中文标题】如何从 STL 类“继承”迭代器?【英文标题】:How to "inherit" an iterator from an STL class? 【发布时间】:2014-01-16 19:11:15 【问题描述】:

我正在尝试使用我编写的一些算法创建一类称为 tableaux 的对象,它们本质上是无符号整数向量的向量(它们就像矩阵,除了行可以是不同的长度)。主要问题是我想从vector类继承这些对象的迭代器,我不知道怎么做。

我已经阅读了几个相关的问题和答案,我很容易公开继承std::vector<std::vector<unsigned int> >,但一致认为这是不好的,因为 STL 容器没有虚拟析构函数或其他任何东西。所以我决定尝试通过组合来“继承”。这是我要实现的目标的一个很小的示例:

#include <vector>
#include <iostream>

class tableau 
  private:
    std::vector<std::vector<unsigned int> > rep;
  public:
    using std::vector<std::vector<unsigned int> >::iterator;
    void push_back(std::vector<unsigned int> const& new_row) 
      rep.push_back(new_row);
    
;

int main() 
  tableau t1;
  std::vector<unsigned int> row1(10);
  std::vector<unsigned int> row2(8);

  t1.push_back(row1);
  t1.push_back(row2);

  tableau::iterator it = t1.begin();
  for ( ; it != t1.end(); ++it) 
    //display rows of tableau
  
  return 0;

然后 g++ 给了我错误:类型“std::vector&lt;std::vector&lt;unsigned int&gt; &gt;”不是类型“tableau”的基本类型。我刚刚开始学习 C++,所以如果我做了一些愚蠢的事情,请保持温柔。如果您想要更多我编写的实际代码,请告诉我。

【问题讨论】:

总的来说,这是一个非常好的测试用例。做得好。 :) 【参考方案1】:

您的第一个问题是using 不允许您从任意不相关类型中窃取类型(尽管您可以为此使用typedef)。另外,您没有begin()end() 成员。

解决这些问题会产生以下结果:

#include <vector>
#include <iostream>

class tableau 
  private:
    std::vector<std::vector<unsigned int> > rep;
  public:
    typedef std::vector<std::vector<unsigned int> >::iterator iterator;
    void push_back(std::vector<unsigned int> const& new_row) 
      rep.push_back(new_row);
    
    iterator begin()  return rep.begin(); 
    iterator end()    return rep.end();   
;

int main() 
  tableau t1;
  std::vector<unsigned int> row1(10);
  std::vector<unsigned int> row2(8);

  t1.push_back(row1);
  t1.push_back(row2);

  tableau::iterator it = t1.begin();
  for ( ; it != t1.end(); ++it) 
    //display rows of tableau
  
  return 0;

但是,您的方法意味着您将不得不包装您想要调用的每一个函数。

如果我是你,我会坚持继承:虽然你引用的建议是正确的,但这并不意味着继承是不可能的。您永远不会希望通过指向基址的指针多态地使用您的tableau,因此只需记录任何人都不应该尝试这样做,您会没事的。

(当你使用“组合”时,它被称为“组合”。你问的是如何“组合”向量。)

【讨论】:

好的,现在作曲的概念更有意义了,谢谢。我想在这种情况下我会坚持继承。 @Joseph:我认为这很明智。 +1 容器的继承并没有一些人试图做到的那么糟糕。

以上是关于如何从 STL 类“继承”迭代器?的主要内容,如果未能解决你的问题,请参考以下文章

STL迭代器相关的输出迭代器

C++ STL 基础及应用 迭代器

STL 迭代器继承:“value_type”未命名类型

STL源码剖析——iterators与trait编程#1 尝试设计一个迭代器

c++中的细化和继承

如何从 STL 列表中的迭代器访问指向结构的指针而不是其元素