使用迭代器隐藏内部容器并在基本容器上实现泛型操作

时间:2010-02-03 12:13:20

标签: c++ iterator

我基本上希望有一个基本容器类,它可以返回一个泛型迭代器,可以用来遍历容器类的实例,而不需要指定迭代器模板。我想我不能在类模板上实现基本容器,这样就需要基于模板类的遍历算法,而这些模板类是事先不知道的。可以使用任何(自定义或标准)容器类型/实现继承和实现基本容器。以下是一些明确的代码示例:

struct MyObject {
  int myInt;
}

// an abstract container
class BaseContainer {
public:
  virtual void insertMyObject(MyObject& obj) = 0;
  virtual iterator getFirst(); // the iterator type is for demonstration purposes only
  virtual iterator getLast();  // the iterator type is for demonstration purposes only
}

// Sample container class that uses a std::vector instance to manage objects
class BaseContainer_Vector : public BaseContainer {
public:
  void insertMyObject(MyObject& obj); // e.g. just pushes back to the vector
  iterator getFirst(); // needs to override the iterator?
  iterator getLast();  // needs to override the iterator?
private:
  std::vector<MyObject> objectContainer;
}

然后我将有一个容器对象列表,我想迭代这些容器和存储的对象。

std::vector<MyContainer*> containers;
for(int i=0 ; i<containers.size() ; i++){
  iterator i    = containers[i]->getFirst();
  iterator iend = containers[i]->getLast();
  for(; i != iend ; i++) {
    std::cout << (*i).myInt << std::endl;
  }
}

我还想支持boost foreach宏声明。只要range_begin和range_end函数正确,它就支持扩展。但是,boost doc中的示例使用std :: string :: iterator作为返回类型,而我需要的是一个泛型迭代器类,我还不知道如何做到这一点。

std::vector<MyContainer*> containers;
for(int i=0 ; i<containers.size() ; i++){
  BOOST_FOREACH(MyObject obj, *(containers[i])) {
    std::cout << obj.myInt << std::endl;
  }
}

我认为我可以定义自己的迭代器类,然后扩展BaseContainer的每个类都应该定义自己的迭代器,扩展该基本迭代器。然而,我更喜欢使用标准迭代器(stl或boost)来支持这个结构,而不是编写我自己的迭代器。我想这种方法可行,但我对其效率的评论持开放态度。

是否有一种可行的方法可以优雅地解决这个问题?或者我错过了一个简单的观点来解决这个问题而没有任何痛苦?

可以找到一个类似的问题here,但建议的解决方案对我的需求来说似乎有点复杂,而且我的理解要求也各不相同。

1 个答案:

答案 0 :(得分:1)

这会很复杂。

如前所述,首先你需要你的迭代器具有值语义,因为它们通常被复制,否则会导致对象切片。

class BaseContainer
{
protected:
  class BaseIteratorImpl; // Abstract class, for the interface

public:
  class iterator
  {
  public:
    iterator(const BaseIteratorImpl& impl);
  private:
    BaseIteratorImpl* m_impl;
  };

  iterator begin();
  iterator end();
}; // BaseContainer

然后,BaseIterator将所有方法转发到m_impl

通过这种方式,您可以使用多态核心实现价值语义语法。

显然,你必须处理深层复制语义和正确的破坏。

一些注意事项:

  • 同时发布iteratorconst_iterator
  • 为您的方法命名emptysizebeginend等...以便与STL算法兼容

您可以查看SGI Iterators以获取有关操作员应支持的概念和操作的帮助,以获得最大兼容性。