1

我有一个boost::intrusive::list<Foo, constant_time_size<false>>, whereFoolist_base_hook<auto_unlink>钩子继承。使用列表元素foo,我可以通过调用来获取它的迭代器list::s_iterator_to(foo)。我的问题是如何使用此迭代器遍历列表。特别是,有没有办法判断这个元素是否是列表中唯一的一个?

消息来源建议在其价值特征中list使用 a cicular_list_algorithms,也许我可以使用以下测试?

auto itr1 = list_t::s_iterator_to(foo);
auto itr2 = list_t::s_iterator_to(foo);
&(*++itr1) == &(*--itr2);

它看起来很hacky,但它似乎有效。我不确定它是否正确和惯用。有人可以建议吗?

完整清单:

#include <iostream>
#include <boost/intrusive/list.hpp>

using namespace boost::intrusive;

typedef list_base_hook<link_mode<auto_unlink> > auto_unlink_hook;

class Foo : public auto_unlink_hook
{
    int int_;
    public:
    Foo(int i = 0)   :  int_(i)  {}
    int  get_int()    { return int_; }
    void unlink()     {  auto_unlink_hook::unlink(); }
    bool is_linked()  {  return auto_unlink_hook::is_linked();  }
};

int main()
{
    typedef list<Foo, constant_time_size<false>> ListType;
    ListType l;
    Foo foo1{42};
    l.push_back(foo1);

    auto itr1 = ListType::s_iterator_to(foo1);
    auto itr2 = ListType::s_iterator_to(foo1);
    std::cout << (&(*++itr1) == &(*--itr2)) << std::endl;

    Foo foo2{43};
    l.push_back(foo2);
    itr1 = ListType::s_iterator_to(foo1);
    itr2 = ListType::s_iterator_to(foo1);
    std::cout << (&(*++itr1) == &(*--itr2)) << std::endl;

    foo1.unlink();

    return 0;
}

是的,我确实意识到取消引用++itr1并且--itr1是错误的。有什么方法可以直接比较底层节点的地址吗?我想它的前身和后继都有链接,如果是唯一的元素foo,它们应该彼此相等。foo

4

1 回答 1

1

我试过这些,它奏效了。但是,它与实现细节紧密耦合。这个想法是从值中获取底层节点指针并比较指针。

typedef list<Foo, constant_time_size<false>> ListType;                                    
ListType l;                                                                               
Foo foo1{42};                                                                             
l.push_back(foo1);                                                                        

ListType::const_node_ptr cur = ListType::value_traits::to_node_ptr(foo1);                 
std::cout << (ListType::node_traits::get_previous(cur) == ListType::node_traits::get_next(cur)) << std::endl;

Foo foo2{43};                                                                             
l.push_back(foo2);                                                                        
std::cout << (ListType::node_traits::get_previous(cur) == ListType::node_traits::get_next(cur)) << std::endl;
于 2018-01-28T11:16:17.073 回答