Как перенести узлы между двумя объектами boost :: intrusive :: slist - PullRequest
2 голосов
/ 28 июня 2019

Допустимо ли передавать узлы между двумя 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);

Я получаю ошибку сегментации и ошибку подтверждения с буст-версией 1.70.0 https://wandbox.org/permlink/nWHakTYUiVBGKH6I. Как я могу это исправить?


Примечание: я не могу выделить новый узел и скопировать старый, потому что я использую навязчивый список, чтобы контролировать, когда и где происходит распределение.

1 Ответ

0 голосов
/ 28 июня 2019

Похоже, цель метода 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
...