我正在学习侵入式列表:
#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()'失败。
答案 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;
}