Зачем использовать функцию push_back для навязчивого списка, требующую lvalue? - PullRequest
0 голосов
/ 23 сентября 2019

Я изучаю навязчивый список:

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


struct DummyObject : public boost::intrusive::list_base_hook<>{
  double price;

  DummyObject(const double a): price(a){

  }
};

using IntrusiveListContainer = boost::intrusive::list<DummyObject>;
using NonintrusiveListContainer = std::list<DummyObject>;

int main()
{

  IntrusiveListContainer  intrusivecontainer;
  NonintrusiveListContainer  nonintrusivecontainer;

  intrusivecontainer.push_back(DummyObject (22.2)); // ERROR
  nonintrusivecontainer.push_back(DummyObject (22.2));// compiled

  return 0;
}

Я понимаю основную идею навязчивого списка, но не могу понять, почему push_back специально требует lvalue.С логической точки зрения, почему навязчивый список не может справиться с rvalue?

Требует ли lvalue, что пользователь должен сам обрабатывать жизненный цикл DummyObject?Другими словами, когда IntrusiveList pop_front, всплывающий объект не будет уничтожен?

Кроме того, событие, которое я передаю по lvalue:

int main()
{

  IntrusiveListContainer  intrusivecontainer;
  NonintrusiveListContainer  nonintrusivecontainer;
  DummyObject a(22.2);
  intrusivecontainer.push_front(a); // compiled
  //nonintrusivecontainer.push_back(DummyObject (22.2));// compiled

  return 0;
}

, двоичный файл не смог выполнить одно из утверждений:

intrusivelist: / usr / include / boost / intrusive / detail /generic_hook.hpp: 48: void boost :: intrusive :: detail :: destructor_impl (Hook &, boost :: intrusive :: detail :: link_dispatch <(boost :: intrusive :: link_mode_type) 1>) [с Hook = boost ::intrusive :: generic_hook <(boost :: intrusive :: algo_types) 0, boost :: intrusive :: list_node_traits, boost :: intrusive :: dft_tag, (boost :: intrusive :: link_mode_type) 1, (boost :: intrusive ::base_hook_type) 1>]: сбой подтверждения `! hook.is_linked () '.

1 Ответ

1 голос
/ 23 сентября 2019

Это простой навязчивый контейнер, который не выполняет управление памятью.Вы несете ответственность за то, чтобы сохраняемый объект пережил навязчивый контейнер.

Это указано в документации:

Нарушающие и не навязчивые контейнеры - 1.64.0

  • Пользователь должен управлять временем жизни вставленных объектов независимо от контейнеров.

Теперь временный объект будет жить короче, чемнавязчивый контейнер, ведущий к неопределенному поведению, навязчивый контейнер не создает никакой копии.поэтому использование r-значения нежелательно.

Теперь эта версия вашего примера отлично работает (без сбоев):

int main()
{
  DummyObject a(22.2);
  IntrusiveListContainer  intrusivecontainer;
  NonintrusiveListContainer  nonintrusivecontainer;

  intrusivecontainer.push_back(a); // ERROR
  nonintrusivecontainer.push_back(a);// compiled

  return 0;
}

И с другой стороны, эта версия заканчивается ошибкой утверждения :

int main()
{
  IntrusiveListContainer  intrusivecontainer;
  NonintrusiveListContainer  nonintrusivecontainer;
  DummyObject a(22.2);

  intrusivecontainer.push_back(a); // ERROR
  nonintrusivecontainer.push_back(a);// compiled

  return 0;
}
...