std :: moveのタイプは何ですか?

このコードは期待通りに動作します(オンラインここ)。 最後の v は空であり、 v の内容は削除されていないので、 w は空ではありません。

    vector v;
    v.push_back(1);
    cout << "v.size(): " << v.size() << endl;
    auto vp = move(v);
    vector w(vp);
    cout << "w.size(): " << w.size() << endl;
    cout << "v.size(): " << v.size() << endl;

しかし、 auto vp = move(v)

    vector && vp = move (v);

それから動かない。代わりにそれはコピーし、両方のベクトルは最後に空ではありません。 こちらに示されています。

Clarification: More specifically, what is the auto-derived type of vp? If it's not vector &&, then what else could it be? Why do the two examples give different results despite being so similar?

Extra: I also tried this, and it still copied instead of moving

    std :: remove_reference< vector > :: type && vp = move(v);
4
確かに、 vector remove_reference だけで、わかるように vector を得ることができます。
追加された 著者 Aaron McDaid,
私は std :: remove_reference :: :: type && vp = move(v); を試してみました。それはコピーではなく、動く。
追加された 著者 Aaron McDaid,

3 答え

Edit for OP's clarification: the auto-derived type of move(v) is vector. See C++11 "auto" semantics.

1番目の例はこれを行います:

move 'v' into 'vp'
copy 'vp' into 'w'

2番目の例はこれを行います:

set 'vp' as rvalue-reference of 'v'
copy 'vp' (which is 'v') into 'w'

std:move は、型をrvalueにキャストするだけです( std: :move()、いつ使用する必要がありますか?)。したがって、

vector&& vp = move(v);

rvalue-reference vp v に設定して何もしないだけです。また、rvalue-referenceは左辺値です(名前があります)。

vector w(vp);

v v )を w にコピーするコピーコンストラクタを呼び出します。

vp に右値()を設定すると、移動コンストラクタが呼び出されます。

vector w(move(vp))

C ++評価値参照の説明 を読むことができます。 。

12
追加された
@AaronMcDaid: v を呼び出さずに、コピーコンストラクタを呼び出すのはです。更新を参照してください。
追加された 著者 kennytm,
この答えは正しい、+1。
追加された 著者 Xeo,
これは実際に一方通行がなぜ機能するのかを説明するものではありませんが、他方は通用しません。
追加された 著者 Seth Carnegie,
しかし、最初の例ではコピーコンストラクタを呼び出すことはありません。 auto vp = move(v); vector w(vp)が動作します(データはぴったりです)。なぜこれは機能しますか?自動派生型vpとは何ですか?
追加された 著者 Aaron McDaid,
2年前から自分の質問を振り返ります。私は move が実際に何かをして副作用を起こしたという印象を受けていることがわかります。また、 auto 型は参照であると仮定しました。両方のカウントで間違っています。
追加された 著者 Aaron McDaid,

最初のケースでは:

auto vp = move(v);

次のものと同等です。

vector vp = move(v);

This invokes the move constructor, since move(v) has type vector&&, hence vp ends up pilfering the contents of v.

第2の場合:

vector&& vp = move(v);

単に vp v のr値参照にします。これにより、移動コンストラクタまたはコピーコンストラクタが呼び出されることはなく、何も処理されません。

2
追加された
auto vp = move(v);

Is creating a new vector and calling it's move constructor:

vector(const vector&& other);

v の内容を盗みます。

So type of 'vp' is simply vector .. no references involved:

vector vp;

それは実際のベクトル自体ではなく、内部を「動かす」。

So &vp will be different to &v .. but the contents will move across.

1
追加された