以下代码尝试创建二叉树的节点并向其返回 boost::shared_ptr()。
void create_node(shared_ptr &in,
unsigned var_name,
shared_ptr left=shared_ptr(),
shared_ptr right=shared_ptr()) {
typename nodes::pointer p = A.allocate(1);
// a temporary node element is created on the stack here.
A.construct(p, (node(var_name, left, right)));
in = shared_ptr(p);
}
查看 libstdc++ 代码,我发现我正在调用的 std::allocator 函数如下所示:
pointer
allocate(size_type __n, const void* = 0)
{
if (__n > this->max_size())
std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
void
construct(pointer __p, const _Tp& __val)
{ ::new((void *)__p) _Tp(__val); }
分配器使用in-placement new来分离内存的分配和对象的构造。因此,可以获取大量元素并在真正需要对象时仅调用构造函数。
该create_node
函数使用分配器概念创建单个对象,并在需要时使用 shared_ptr 调用析构函数。为了使这些单一分配便宜,我想稍后替换分配器(因此我想要一个使用池分配的分配器)。
当我调用此函数时,它将在堆栈上创建一个临时实例,然后将节点的元素复制到堆位置。如何强制编译器立即就地创建对象?因此,我想要一个倒置的命名返回值优化 (NRVO)。这可能吗?