使用boost :: iterator_facade<> [英] Using boost::iterator_facade<>

查看:546
本文介绍了使用boost :: iterator_facade<>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个链表结构:

  struct SomeLinkedList 
{
const char * bar;
int lots_of_interesting_stuff_in_here;
DWORD foo;
SomeLinkedList * pNext;
};

它是现有API的一部分,我无法更改。 / p>

我想添加迭代器支持。 boost :: iterator_facade<> 库似乎是理想的目的。

  class SomeIterator 
:public boost :: iterator_facade< SomeIterator,
const SomeLinkedList,
boost :: forward_traversal_tag>
{
public:
SomeIterator():node_(NULL){};

explicit SomeIterator(const SomeLinkedList * p):node_(p){};

private:
friend class boost :: iterator_core_access;

void increment(){node_ = node _-> pNext; };

bool equal(SomeIterator const& other)const {/ * some comparison * /; };

SomeLinkedList const& dereference()const {return * node_; };

SomeLinkedList const * node_;
}; // class SomeIterator

目标是能够在标准库函数中使用它,例如 std :: for_each

  void DoSomething(const SomeLinkedList * node); 

SomeLinkedList * my_list = CreateLinkedList();
std :: for_each(SomeIterator(my_list),SomeIterator(),DoSomething);

不幸的是,我收到一个错误,说它试图通过值传递列表,而不是通过指针。

 错误C2664:'void(const SomeLinkedList *)':无法将参数1从'const SomeLinkedList' *'

如何更改 SomeIterator





$ b

$ b

编辑:
我试过这个:

  class SomeIterator 
:public boost :: iterator_facade< SomeIterator,
SomeLinkedList,
boost :: forward_traversal_tag,
SomeLinkedList *>
{
// ...

但我得到这个编译器错误:

 错误C2664:'boost :: implicit_cast':无法将参数1从'SomeLinkedList **'转换为'boost :: detail :: operator_arrow_proxy< T> 






编辑2:



我尝试修改引用类型:

  class SomeIterator 
:public boost :: iterator_facade< SomeIterator,
const SomeLinkedList,
boost :: forward_traversal_tag>
{
// ...

const SomeLinkedList * dereference()const {return node_; };

但我得到原始错误:

 错误C2664:'void(const SomeLinkedList *)'无法将参数1从'const SomeLinkedList'转换为'const SomeLinkedList *'


解决方案

当你的迭代器被解引用时,它会返回一个 const SomeLinkedList& 然而你的DoSomething函数期待一个 const SomeLinkedList * 。当解除引用或改变你的DoSomething函数时,可以改变迭代器以某种方式返回指针。






/ p>

我实际上没有使用boost :: iterator_facade,但是看看你发布的其他代码,你可能没有改变全部



您实际上是否尝试过

  SomeIterator 
:public boost :: iterator_facade< SomeIterator,
SomeLinkedList,
boost :: forward_traversal_tag,
SomeLinkedList *>
{

  const SomeLinkedList * dereference()const {return node_; }; 

在一起?



'work,then how:

  class SomeIterator 
:public boost :: iterator_facade< SomeIterator,
SomeLinkedList *,
boost :: forward_traversal_tag>
{

const SomeLinkedList * dereference()const {return node_; };

或者,如davka在注释中建议的,通过创建一个包装来解决指针vs引用问题周围DoSomething?如:

  void DoSomethingWrapper(const SomeLinkedList& node)
{
DoSomething(& node) ;
}

事实上,你可能甚至保持包装器的名称与函数它包装,只是让重载规则处理当指针或引用版本被调用时。


I have a linked list structure:

struct SomeLinkedList
{
    const char* bar;
    int lots_of_interesting_stuff_in_here;
    DWORD foo;
    SomeLinkedList* pNext;
};

It is part of an existing API and I cannot change it.

I would like to add iterator support. The boost::iterator_facade<> library seemed ideal for the purpose.

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     const SomeLinkedList, 
                                     boost::forward_traversal_tag >
{
public:
    SomeIterator() : node_( NULL ) {};

    explicit SomeIterator( const SomeLinkedList* p ) : node_( p ) {};

private:
    friend class boost::iterator_core_access;

    void increment() { node_ = node_->pNext; };

    bool equal( SomeIterator const& other ) const { /*some comparison*/; };

    SomeLinkedList const& dereference() const { return *node_; };

    SomeLinkedList const* node_;
}; // class SomeIterator

The goal is to be able to use it in standard library functions like std::for_each

void DoSomething( const SomeLinkedList* node );

SomeLinkedList* my_list = CreateLinkedList();
std::for_each( SomeIterator( my_list ), SomeIterator(), DoSomething );

Unfortunately, I'm getting an error saying it's trying to pass the list by value rather than by pointer.

error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'

How can I change SomeIterator to do to get this working correctly?

Thanks, PaulH


Edit: I've tried this:

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList, 
                                     boost::forward_traversal_tag,
                                     SomeLinkedList* >
{
    // ...

but I get this complier error:

error C2664: 'boost::implicit_cast' : cannot convert parameter 1 from 'SomeLinkedList **' to 'boost::detail::operator_arrow_proxy<T>


Edit 2:

I've tried modifying the dereference type:

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     const SomeLinkedList, 
                                     boost::forward_traversal_tag >
{
    // ...

    const SomeLinkedList* dereference() const { return node_; };

but, I get the original error:

error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'

解决方案

When your iterator is dereferenced, it would return a const SomeLinkedList& however your DoSomething function is expecting a const SomeLinkedList*. Either alter the iterator to somehow return pointers when dereferenced or alter your DoSomething function.


EDIT in response to further discussion:

I haven't actually used boost::iterator_facade myself, but looking at additional code you posted it appears you might not have changed all the necessary parts at the same time.

Have you actually tried

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList, 
                                     boost::forward_traversal_tag,
                                     SomeLinkedList* >
{

and

const SomeLinkedList* dereference() const { return node_; };

together?

Or if that doesn't work, then how about:

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList*, 
                                     boost::forward_traversal_tag>
{

const SomeLinkedList* dereference() const { return node_; };

Alternatively, as davka suggested in a comment, what about solving the pointer vs reference issue by making a wrapper around DoSomething? Such as:

void DoSomethingWrapper( const SomeLinkedList& node )
{
    DoSomething(&node);
}

In fact, you could probably even keep the wrapper the same name as the function it wraps and just let overloading rules take care of when the pointer or reference version gets called.

这篇关于使用boost :: iterator_facade&lt;&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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