使用迭代器隐藏内部容器并在基础容器上实现通用操作 [英] Using Iterators to hide internal container and achieve generic operation over a base container

查看:11
本文介绍了使用迭代器隐藏内部容器并在基础容器上实现通用操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上想要一个基础容器类,它可以返回一个通用迭代器,该迭代器可用于遍历容器类的实例,而无需指定迭代器模板.我认为我无法通过类模板实现基本容器,这将需要基于事先不知道的模板类的遍历算法.可以使用其中的任何(自定义或标准)容器类型/实现来继承和实现基本容器.这里有一些代码示例可以清楚地说明:

I basically want to have a base container class which can return a generic iterator that can be used to traverse an instance of the container class, without needing to specify iterator templates. I think I cannot implement the base container over a class template, which would then require a traversal algorithm based on template classes which are not known in advance. The base container can be inherited and implemented using any (custom or standard) container type/implementation within. Here are some code samples to make it clear:

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;
}

然后我将有一个容器对象列表,并且我想遍历这些容器和存储的对象.

I will then have a list of container objects, and I want to iterate over both these containers and the objects stored.

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 作为返回类型,而我需要的是一个通用的迭代器类,我还不知道如何做到这一点.

I further would like to have support for boost foreach macro statement. It supports extensions as long as range_begin and range_end functions are properly. But, the example in boost doc uses std::string::iterator as return type, while what I need is a generic iterator class and I could not yet figure out how to do that as well.

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)来支持这种结构,而不是编写自己的迭代器.我想这种方法会奏效,但我愿意就其效率发表评论.

I think I can define my own iterator class, then each class that extends BaseContainer should define their own iterator extending that basic iterator. Yet, I would prefer to use standard iterators (stl or boost) to support this structure, rather that writing my own iterators. I guess this approach will work, but I am open to comments regarding its efficiency.

有没有可行的方法可以优雅地解决这个问题?还是我错过了一个可以毫无痛苦地解决这个问题的简单点?

Is there a feasible approach that can solve this problem elegantly? Or am I missing a simple point which can solve this problem without any pain?

可以找到类似的问题 这里,但建议的解决方案对我的需求来说似乎有点复杂,而且据我所知,要求有所不同.

A similar question can be found here, but the proposed solutions seem a bit complex for my needs, and the requirements differ as far as I can understand.

推荐答案

这会很复杂.

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

As already stated, first you need your iterators to have value semantic because since they are usually copied around otherwise it would result in object slicing.

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.

Then, BaseIterator forwards all methods to m_impl.

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

This way you achieve value semantic syntax with a polymorphic core.

显然,您必须处理深拷贝语义和适当的破坏.

Obviously, you'll have to handle deep-copy semantics and proper destruction.

一些注意事项:

  • 同时发布 iteratorconst_iterator
  • 将您的方法命名为 emptysizebeginend 等...以与 STL 算法兼容
  • publish both an iterator and a const_iterator class
  • name your methods empty, size, begin, end etc... for compatibility with STL algorithms

您可以查看SGI Iterators 以获得有关您的概念和操作的帮助运营商应该支持最大的兼容性.

You can check SGI Iterators for help about the Concepts and operations your operators should support for maximum compatibility.

这篇关于使用迭代器隐藏内部容器并在基础容器上实现通用操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆