から戻った後、new_S
「RValueベクター」はありません(コンストラクターへの右辺値参照パラメーターを意味すると思います)。右辺値参照は、S の構築中にのみ存在します。
あなたのコードへのいくつかの単語: std::forward
is wearg here. unviersal 参照を完全に転送するためにのみ必要でstd::vector<T>
あり、universal ref ではなく rvalue ref (see here)を uns します。std::move
この場合に使用します。
そうは言っても、コンストラクターで rvalue-ref を渡すべきではありません。代わりに、値で渡します。
struct S
{
S(std::vector<T> s) : s_{std::move(s)} {}
std::vector<T> s_;
};
そうすれば、渡された値に対して最適なソリューションが得られます。ここを参照してください。
- 右辺値が渡された場合、
s
は引数から移動構築され、その後s_
は から移動構築されs
ます。コピーは作成されません。
- 左辺値が渡された場合
s
はコピー構築され、その後s_
は from から移動構築されs
ます。必要なコピーが 1 つだけ作成されます。
new
最後になりましたが、生のポインターと/を使用しないでくださいdelete
。代わりに、スマート ポインターを使用します。
unique_ptr<S> new_S()
{
return std::make_unique<S>({{1}, {2}, {3}});
}
make_unique
C++14 が付属しているため、ライブラリにまだない場合は、簡単に自分で作成できます。
更新:
オブジェクトの有効期間に関する質問に答えるにnew_S
は: では、基本的に 4 つまたは 5 つのオブジェクトがあります。
- 構築される S とその中のベクトル
- コンストラクタに渡すイニシャライザ リスト
- 初期化子リストから構築された一時的なベクトル
- 関数の記述では、パラメーター
s
はそれ自体のオブジェクトです。
今何が起こるか:
- イニシャライザ リストは、コンストラクタに渡される右辺値である一時的なベクトル オブジェクトを作成するために使用されます。テンポラリの構築中に、ベクトル内に 3 つの T を配置するために 1 つのメモリ チャンクが割り当てられます。
- あなたの文章では、コンストラクターの rvalue ref パラメーターは一時的にバインドされています。私の執筆で
s
は、ベクトルの移動コンストラクターを呼び出す一時的な呼び出しで初期化されます。その後、一時は空になりs
、T を持つメモリのチャンクを所有します。
- の初期化で
s_
、パラメータが移動されます。つまり、s_
(あなたの文章では) 一時的なものから、またはs
(私の文章では) から構築された移動を取得します。その後、temporary/s
は空になりs_
、ステップ 1 で割り当てられたメモリのチャンクを所有します。
s_
適切に構築されており、有効なオブジェクトです。オブジェクトX
が「無効」になるのは、移動するとき、つまり を呼び出したときだけですmove(X)
。Y
別のオブジェクトをそこに移動して構築したオブジェクト(X
つまり、 を介して移動構築することauto Y = move(X);
) は決して無効ではありません。構築時にオブジェクトを無効にすることは非常に悪いことであり、役に立たないでしょう。C++ は壊れた言語になります。