次のコードは、バイナリツリーのノードを作成し、それに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); }
アロケータは、インプレースメントnewを使用して、メモリの割り当てとオブジェクトの構築を分離します。したがって、大量の要素を取得し、オブジェクトが本当に必要な場合にのみコンストラクターを呼び出すことができます。
このcreate_node関数は、アロケータの概念を使用して単一のオブジェクトを作成し、shared_ptrを使用して必要に応じてデストラクタを呼び出します。これらの単一の割り当てを安価にするために、後でアロケータを交換したいと思います(したがって、プール割り当てを使用するアロケータが必要です)。
この関数を呼び出すと、スタック上に一時インスタンスが作成され、ノードの要素がヒープの場所にコピーされます。コンパイラにオブジェクトをすぐに作成させるにはどうすればよいですか?したがって、逆の名前付き戻り値最適化(NRVO)が必要です。これは可能ですか?