c++ - 如何使用 boost::iterator_facade 访问遗留链表

标签 c++ boost

作为尝试理解如何使用 boost::iterator_facade 的一部分,我从这个问题 Using boost::iterator_facade<> 中提取了一些代码。并让它运行起来。我完成的代码如下。我的问题涉及 std::for_each 和 std::find 算法中的 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;
}

最佳答案

这是一个通用的做法,没有必要改变它。如果您查看 iterator标题,你会发现std::istream_iterator<> ,例如,采用类似的方法,end iterator 是一个比较 istream_iterator<T>() 的特殊迭代器值 ( true )任何已完成迭代的迭代器,无论它是从哪个输入流初始化的。

关于c++ - 如何使用 boost::iterator_facade 访问遗留链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7962095/

相关文章:

c++ - QT Framework C++ 我如何从另一个类访问 progressBar

c++ - 使与 IPv6 或 IPv4 的连接变得容易?

c++ - C++ 中短格式 "if"的 Python 等效项

python - 使用默认参数将特定参数传递给 Boost Python 函数

c++ - 如何复制 boost 信号的槽

c++ - 无法解锁 boost asio 接受器

c++ - 为什么 clang 将其解析为用户定义的文字?

c++ - 发布者和消费者线程之间通过堆栈共享数据

c++ - Boost 池分配器不会在 g++ 中使用 std::allocate_shared 进行编译

c++ - 在 Boost 周围使用 "#pragma warning"时出现警告 C4503 包括