いくつかの記事を読んでいるときに、この行が非常に不可解であることがわかりました。
new (new_ptr + i) T(std::move(old_ptr[i]));
誰かがこの構文がどのように機能するかを説明できますか?
いくつかの記事を読んでいるときに、この行が非常に不可解であることがわかりました。
new (new_ptr + i) T(std::move(old_ptr[i]));
誰かがこの構文がどのように機能するかを説明できますか?
良いニュースは、どれも新しい構文ではないということです (しかし、すべてがnew
構文です、ホーホー!)。C++11で導入された関数が使われていますが、std::move
それだけです。
行の構文は配置new
と呼ばれ、かなり前から存在しています。メモリ内のすでに割り当てられているスペースにオブジェクトを作成できます。ここで、すでに割り当てられているメモリはポインタで与えられますnew_ptr + i
。そこで作成されるオブジェクトのタイプはT
.
new の配置の単純で無意味な例は次のとおりです。
int* p = new int(); // Allocate and initialise an int
new (p) int(); // Initialise a new int in the space allocated before
のコンストラクタT
が渡されていstd::move(old_ptr[i])
ます。old_ptr
タイプ のオブジェクトにポイントがあると仮定するとT
、この移動により、 の移動コンストラクタをT
使用してオブジェクトを作成できます。それは基本的にそれold_ptr[i]
が一時的なT
オブジェクトであるふりをして (実際にはそうでなくても)、新しいT
ものをそこから盗むことを可能にします。これについて詳しくは、移動セマンティクスを調べてください。
その配置。
new (new_ptr + i) T(std::move(old_ptr[i]));
ここで、これを次のように簡略化できます。
new (<destinationLocation>) T(<constructor parameters);
これは通常のC++03であり、基本的に、事前に割り当てたメモリ領域にオブジェクトを動的に作成できます(ほとんどの人が使用しない高度な手法です(オブジェクトのような独自のコンテナを構築している場合を除く))。 。
std :: move()部分はC ++ 11からのものであり、moveコンストラクターを型Tで使用できるようにする特別な参照型を作成しています。
new T(std::move(<source Obj>));
これは基本的に、ソースオブジェクトを使用して新しいTを作成し、効率を上げるためにmoveコンストラクターを使用することを意味します。これは、移動後に「ソースObj」が未定義の状態(したがって使用できない)のままになることを意味しますが、効率的なオブジェクトの作成が可能になります。
この2つを組み合わせると、配列の要素をソースオブジェクトとして使用して、新しい配置と移動構造が得られます。