首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用boost::iterator_facade<>

使用boost::iterator_facade<>
EN

Stack Overflow用户
提问于 2010-08-18 16:42:54
回答 2查看 8.2K关注 0票数 3

我有一个链接的列表结构:

代码语言:javascript
复制
struct SomeLinkedList
{
    const char* bar;
    int lots_of_interesting_stuff_in_here;
    DWORD foo;
    SomeLinkedList* pNext;
};

它是现有API的一部分,我不能更改它.

我想添加迭代器支持。boost::iterator_facade<>库似乎很适合这一目的。

代码语言:javascript
复制
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 )中使用它。

代码语言:javascript
复制
void DoSomething( const SomeLinkedList* node );

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

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

代码语言:javascript
复制
error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'

如何更改SomeIterator以使其正常工作?

谢谢,PaulH

编辑:我试过这样做:

代码语言:javascript
复制
class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList, 
                                     boost::forward_traversal_tag,
                                     SomeLinkedList* >
{
    // ...

但我发现了一个编辑错误:

代码语言:javascript
复制
error C2664: 'boost::implicit_cast' : cannot convert parameter 1 from 'SomeLinkedList **' to 'boost::detail::operator_arrow_proxy<T>

编辑2:

我尝试过修改取消引用类型:

代码语言:javascript
复制
class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     const SomeLinkedList, 
                                     boost::forward_traversal_tag >
{
    // ...

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

但是,我得到了最初的错误:

代码语言:javascript
复制
error C2664: 'void (const SomeLinkedList *)' : cannot convert parameter 1 from 'const SomeLinkedList' to 'const SomeLinkedList *'
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-18 17:04:28

当您的迭代器被取消引用时,它将返回一个const SomeLinkedList&,但是您的DoSomething函数需要一个const SomeLinkedList*。或者更改迭代器,以便在取消引用时以某种方式返回指针,或者更改DoSomething函数。

编辑以回应进一步的讨论:

我本人并没有实际使用boost::iterator_facade,但是看一看您发布的附加代码,您可能没有同时更改所有必要的部分。

你真的试过

代码语言:javascript
复制
class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList, 
                                     boost::forward_traversal_tag,
                                     SomeLinkedList* >
{

代码语言:javascript
复制
const SomeLinkedList* dereference() const { return node_; };

在一起?

或者如果这不起作用,那不如:

代码语言:javascript
复制
class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     SomeLinkedList*, 
                                     boost::forward_traversal_tag>
{

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

或者,正如达夫卡在评论中所建议的那样,如何通过在DoSomething周围设置一个包装器来解决指针与引用之间的问题?例如:

代码语言:javascript
复制
void DoSomethingWrapper( const SomeLinkedList& node )
{
    DoSomething(&node);
}

实际上,您甚至可以将包装器与它包装的函数保持相同的名称,并让重载规则在调用指针或引用版本时负责处理。

票数 1
EN

Stack Overflow用户

发布于 2011-10-31 04:26:40

我一直在努力理解boost::iterator_facade。寻找一个简单的例子,我找到了这个(旧的)问题和一个被接受的答案。我想我会张贴我需要的代码,使这个例子在这里工作,因为现有的问题和答案从来没有真正解决问题。

在第一个实例中,请注意,for_each()的第二个参数是一个结束迭代器。我发现在原始问题代码中使用的空迭代器(不确定这是正确的术语)工作良好,但前提是您完成了.equal()的不完整定义,如下所示;

代码语言:javascript
复制
bool equal( SomeIterator const& other ) const { return node_ == other.node_; }

除此之外,简单地将DoSomething()参数的定义从ptr更改为引用(正如可接受的答案中提到的那样),是编译和运行该参数的关键。我在下面放了一些原始的测试代码来说明。

代码语言:javascript
复制
void DoSomething( const SomeLinkedList& node )
{
    std::cout << "DoSomething " << node.foo << "\n";
}

int main()
{
    SomeLinkedList temp[5];
    memset(temp,0,sizeof(temp));
    temp[0].pNext = &temp[1];
    temp[1].pNext = &temp[2];
    temp[2].pNext = &temp[3];
    temp[3].pNext = &temp[4];
    temp[4].pNext = 0;
    temp[0].foo   = 0;
    temp[1].foo   = 1;
    temp[2].foo   = 2;
    temp[3].foo   = 3;
    temp[4].foo   = 4;
    SomeLinkedList* my_list = &temp[0];
    std::for_each( SomeIterator( my_list ), SomeIterator(), DoSomething );
    return 0;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3514457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档