使我的C ++类通过BOOST_FOREACH可迭代 [英] Make my C++ Class iterable via BOOST_FOREACH

查看:93
本文介绍了使我的C ++类通过BOOST_FOREACH可迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  struct TestData 
{
int x;
int y;
//其他数据以及
}

类IterableTest
{
public:
//在此处显示TestData
} ;

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

  IterableTest测试; 
BOOST_FOREACH(const TestData& data,test.data())
{
//使用数据
执行操作}
pre>

我已阅读过这篇文章 http:// accu .org / index.php / journals / 1527 关于成员空间。
然而,我不想(或不能)将所有TestData保存在内部向量或某事中。
这是因为类本身不拥有存储,即实际上没有可以直接由类访问的底层容器。类本身可以查询一个外部组件来获得下一个,上一个或第i个元素。



所以基本上我想让我的类的行为,但事实上它没有一个。
任何想法?

解决方案

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



Boost.Iterator库有很多有用的模板。我已经使用了他们的Iterator Facade基类几次,它很好,很容易定义自己的迭代器使用它。



但是即使没有它,迭代器aren'火箭科学。他们只需要公开正确的操作符和typedef。



一旦你定义了一个迭代器类,你就可以只需要将 begin() end()成员函数添加到您的类中。



这听起来是基本的想法是,当迭代器增加时,必须调用你的查询函数,得到下一个值。
然后deReference应该返回从上次查询调用中检索的值。



这可能有助于看看标准库 stream_iterator s为某些语义,因为他们也必须解决一些鱼腥我们真的没有一个容器,我们不能创建指向除当前流位置之外的迭代器



例如,假设你需要调用一个 query()函数, ve到达序列的末尾,创建一个end-iterator将是棘手的。但实际上,你需要的是定义等式,使如果它们都存储NULL作为它们的缓存值,迭代器是相等的。因此,用NULL初始化end迭代器。



它可能有助于查找输入迭代器所需的语义,或者如果你正在阅读Boost.Iterator ,对于单通过迭代器具体。您可能无法创建多遍迭代器。因此,查看单通过迭代器需要什么行为,并坚持下去。


I have a class which I want to expose a list of structs (which just contain some integers). I don't want the outside to modify these data, just iterate over it and read them Example:

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

class IterableTest
{
  public:
    // expose TestData here
};

now in my code I want to use my class like this:

IterableTest test;
BOOST_FOREACH(const TestData& data, test.data())
{
  // do something with data
}

I've already read this article http://accu.org/index.php/journals/1527 about memberspaces. However, I don't want to (or can't) save all TestData in an internal vector or something. This is because the class itself doesn't own the storage, i.e. there is actually no underlying container which can be accessed directly by the class. The class itself can query an external component to get the next, previous or ith element, though.

So basically I want my class to behave as if it had a collection, but in fact it doesn't have one. Any ideas?

解决方案

It sounds like you have to write your own iterators.

The Boost.Iterator library has a number of helpful templates. I've used their Iterator Facade base class a couple of times, and it's nice and easy to define your own iterators using it.

But even without it, iterators aren't rocket science. They just have to expose the right operators and typedefs. In your case, they're just going to be wrappers around the query function they have to call when they're incremented.

Once you have defined an iterator class, you just have to add begin() and end() member functions to your class.

It sounds like the basic idea is going to have to be to call your query function when the iterator is incremented, to get the next value. And dereference should then return the value retrieved from the last query call.

It may help to take a look at the standard library stream_iterators for some of the semantics, since they also have to work around some fishy "we don't really have a container, and we can't create iterators pointing anywhere other than at the current stream position" issues.

For example, assuming you need to call a query() function which returns NULL when you've reached the end of the sequence, creating an "end-iterator" is going to be tricky. But really, all you need is to define equality so that "iterators are equal if they both store NULL as their cached value". So initialize the "end" iterator with NULL.

It may help to look up the required semantics for input iterators, or if you're reading the documentation for Boost.Iterator, for single-pass iterators specifically. You probably won't be able to create multipass iterators. So look up exactly what behavior is required for a single-pass iterator, and stick to that.

这篇关于使我的C ++类通过BOOST_FOREACH可迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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