2

boost::intrusive::slist<boost::intrusive::cache_last<true>>在两个对象之间传输节点是否有效?类似于以下内容

auto one = boost::intrusive::slist<Node, boost::intrusive::cache_last<true>>{};
auto two = boost::intrusive::slist<Node, boost::intrusive::cache_last<true>>{};

auto node = std::make_unique<Node>();
one.push_back(*node);

auto& front = one.front();
one.pop_front();
two.push_back(front);

我遇到分段错误,以及 boost 版本 1.70.0 https://wandbox.org/permlink/nWHakTYUiVBGKH6I的断言失败。我怎样才能解决这个问题?


注意:我无法分配新节点并复制旧节点,因为我使用侵入式列表来控制分配发生的时间和地点。

4

2 回答 2

0

当节点仍在容器中时,您正在删除节点——安全链接模式会检查这一点并将断言。

如果您先删除容器(重新排序对象构造),或者在清理之前从容器中删除节点,则没有断言。

例如

auto node = std::make_unique<Node>();
auto one = boost::intrusive::slist<Node, boost::intrusive::cache_last<true>>{};
auto two = boost::intrusive::slist<Node, boost::intrusive::cache_last<true>>{};

one.push_back(*node);

auto& front = one.front();
one.pop_front();
two.push_back(front);
于 2020-08-17T15:51:52.130 回答
0

这似乎是该splice方法的目的:

效果:将列表 x 的所有元素转移到此列表中,在它指向的元素之前。不调用析构函数或复制构造函数。

two.splice(two.end(), one, one.begin());

完整的演示:

#include <iostream>
#include <string>
#include <boost/intrusive/slist.hpp>

struct Node : public boost::intrusive::slist_base_hook<>
{
    int         i;
    std::string s;

    Node(int i, std::string s) : i(i), s(std::move(s)) {}
};

using NodeList = boost::intrusive::slist<Node, boost::intrusive::cache_last<true>>;

int main()
{
    NodeList one;
    NodeList two;

    auto show = [&](auto text){
        std::cout <<text <<"\n  one\n";
        for (auto & item : one) { std::cout <<"    " <<item.i <<' ' <<item.s <<'\n'; }
        std::cout <<"  two\n";
        for (auto & item : two) { std::cout <<"    " <<item.i <<' ' <<item.s <<'\n'; }
    };


    one.push_back(*new Node(42, "hello"));
    show("before splice");

    two.splice(two.end(), one, one.begin());
    show("after splice");

    one.clear_and_dispose([](Node * ptr){ delete ptr; });
    two.clear_and_dispose([](Node * ptr){ delete ptr; });
    return 0;
}

运行时,将写入:

before splice
  one
    42 hello
  two
after splice
  one
  two
    42 hello
于 2019-06-28T09:42:11.210 回答