如何使用boost :: iterator_facade访问旧链表

时间:2011-11-01 03:16:35

标签: c++ boost

作为尝试理解如何使用boost :: iterator_facade的一部分,我从这个问题Using boost::iterator_facade<>中选取了一些代码并使其运行。我完成的代码如下。我的问题涉及std :: for_each和std :: find算法中的end参数。我保留了原始问题中我在原始代码中找到的习语。基本上它为end参数使用一种NULL迭代器。只要我按照显示的方式定义了equal()成员,它就可以工作。

我的问题是,这个成语(一个NULL迭代器(?),也许这个类型的迭代器有一个我不知道的真正术语),众所周知和良好的实践。如果没有,你能否推荐另一种方法。

// Element of linked list (legacy code, can't be changed)
struct SomeLinkedList
{
    const char* bar;
    int lots_of_interesting_stuff_in_here;
    long foo;
    SomeLinkedList* pNext;

    // actually I cheated and added this to get std::find working
    bool operator ==( SomeLinkedList const& other ) const { return foo == other.foo; }
};

class SomeIterator
    : public boost::iterator_facade< SomeIterator, 
                                     const SomeLinkedList, 
                                     boost::forward_traversal_tag >
{
public:
    SomeIterator() : node_( NULL ) {};  // used to create end iterators in examples
    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 { return node_ == other.node_; }
    SomeLinkedList const& dereference() const { return *node_; };
    SomeLinkedList const* node_;
}; // class SomeIterator

void DoSomething( const SomeLinkedList& node )
{
    std::cout << "DoSomething " << node.foo << "\n";
}

void main()
{
    // Ugly but effective way to create a fake linked list for experiments
    SomeLinkedList temp[3];
    memset(temp,0,sizeof(temp));
    temp[0].pNext = &temp[1];
    temp[1].pNext = &temp[2];
    temp[2].pNext = 0;
    temp[0].foo   = 0;
    temp[1].foo   = 1;
    temp[2].foo   = 2;
    temp[2].bar   = "number 2";
    SomeLinkedList* my_list = &temp[0];

    // DoSomething() for each element in list
    std::for_each( SomeIterator(my_list), /*end*/ SomeIterator(), DoSomething );

    // Find one element in the list
    SomeLinkedList obj;
    obj.foo = 2;
    SomeIterator it = std::find( SomeIterator(my_list),  /*end*/ SomeIterator(), obj );
    std::cout << "found " << it->bar << "\n";
    return 0;
}

1 个答案:

答案 0 :(得分:1)

这是一种常见的方法,无需更改。如果你查看iterator标题,你会发现std::istream_iterator<>,例如,采用类似的方法,end迭代器是一个特殊的迭代器值(istream_iterator<T>()),将true与已完成迭代的任何迭代器进行比较,无论初始化它的输入流如何。