通过BOOST_FOREACH使我的C++类可迭代

new*_*gre 11 c++ iterator design-patterns

我有一个类,我想要公开一个结构列表(它只包含一些整数).我不希望外部修改这些数据,只是迭代它并读取它们示例:

struct TestData
{
  int x;
  int y;
  // other data as well
}

class IterableTest
{
  public:
    // expose TestData here
};
Run Code Online (Sandbox Code Playgroud)

现在在我的代码中我想像我这样使用我的类:

IterableTest test;
BOOST_FOREACH(const TestData& data, test.data())
{
  // do something with data
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了这篇关于成员空间的文章http://accu.org/index.php/journals/1527.但是,我不想(或不能)将所有TestData保存在内部向量中.这是因为类本身并不拥有存储,即实际上没有可以由类直接访问的底层容器.但是,类本身可以查询外部组件以获取next,previous或iith元素.

所以基本上我希望我的班级表现得好像它有一个集合,但事实上它没有一个.有任何想法吗?

jal*_*alf 5

听起来你必须编写自己的迭代器.

Boost.Iterator库有许多有用的模板.我曾经多次使用过他们的Iterator Facade基类,使用它来定义自己的迭代器很方便.

但即使没有它,迭代器也不是火箭科学.他们只需暴露正确的运算符和typedef.在你的情况下,它们只是围绕它们增加时必须调用的查询函数的包装器.

一旦定义了迭代器类,就必须向类中添加begin()end()成员函数.

听起来基本的想法是在迭代器递增时调用查询函数,以获得下一个值.然后取消引用应返回从上次查询调用中检索到的值.

stream_iterator对于某些语义来说,查看标准库可能会有所帮助,因为它们还必须解决一些可疑问题"我们实际上没有容器,并且我们无法创建指向除了处理器之外的任何地方的迭代器当前流位置"问题.

例如,假设您需要query()在到达序列末尾时调用返回NULL 的函数,那么创建"end-iterator"将会非常棘手.但实际上,您需要的只是定义相等性,以便"迭代器相等,如果它们都将NULL存储为缓存值".所以用NULL初始化"end"迭代器.

查找输入迭代器所需的语义,或者如果您正在阅读Boost.Iterator的文档,特别是单通道迭代器可能会有所帮助.您可能无法创建多通迭代器.因此,请准确查看单通道迭代器所需的行为,并坚持下去.