为什么boost intrusive list的push_back函数需要lvalue?

时间:2019-09-23 15:11:19

标签: c++ rvalue lvalue intrusive-containers boost-intrusive

我正在学习侵入式列表:

#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特别需要左值。从逻辑角度看,为什么侵入式列表不能处理右值?

左值要求是否暗示用户需要自己处理DummyObject的生命周期?换句话说,当IntrusiveList pop_front时,弹出的对象将不会被破坏?

此外,事件我通过左值传递:

int main()
{

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

  return 0;
}

二进制文件失败了一个断言之一:

侵入列表:/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>)[with 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,(提升:: intrusive :: base_hook_type)1>]:断言`!hook.is_linked()'失败。

1 个答案:

答案 0 :(得分:1)

这是一个简单的侵入式容器,不执行内存管理。您有责任确保存储的对象的寿命超过侵入式容器。

这在文档中指出:

Intrusive and non-intrusive containers - 1.64.0

  
      
  • 用户必须独立于容器管理插入对象的生存期
  •   

现在,临时对象的生存期将短于侵入式容器,从而导致未定义的行为,侵入式容器不会创建任何副本。因此不希望使用r值。

现在此版本的示例works fine(不崩溃):

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

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

  return 0;
}

另一方面,该版本ends with assertion failure

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

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

  return 0;
}