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

Why boost intrusive list 's push_back function requires lvalue?

我正在学习侵入式列表:

#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的生命周期?也就是说,当IntrusiveListpop_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挂钩 = 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()' 失败。

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

文档中指出了这一点:

Intrusive and non-intrusive containers - 1.64.0

  • The user has to manage the lifetime of inserted objects independently from the containers.

现在临时对象的寿命会比侵入式容器短,从而导致未定义的行为,侵入式容器不会创建任何副本。因此不需要使用 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;
}