21

右辺値の参照について、私がよく理解していないことがあると思います。以下がエラーでコンパイルに失敗するのはなぜですか(VS2012)'foo' : cannot convert parameter 1 from 'int' to 'int &&'

void foo(int &&) {}
void bar(int &&x) { foo(x); };

int &&barからfooに渡されたときに型が保持されると思いました。int関数本体の中で一度変換されるのはなぜですか?

私は答えが使用することであることを知っていますstd::forward

void bar(int &&x) { foo(std::forward<int>(x)); }

だから多分私は理由を明確に把握していないだけです。(また、なぜstd::moveですか?)

4

5 に答える 5

15

左辺値は、名前があるかアドレス指定できる値として常に覚えています。x には名前があるため、左辺値として渡されます。右辺値への参照の目的は、関数が適切と思われる方法で値を完全に上書きできるようにすることです。あなたの例のように x を参照渡しすると、これを安全に行うことができるかどうかを知る方法がありません。

void foo(int &&) {}
void bar(int &&x) { 
    foo(x); 
    x.DoSomething();   // what could x be?
};

行うfoo(std::move(x));とは、x の使用が終了し、x が不要になったことをコンパイラーに明示的に伝えることです。その動きがなければ、既存のコードに悪いことが起こる可能性があります。はstd::move安全装置です。

std::forwardテンプレートでの完全転送に使用されます。

于 2012-09-26T20:03:13.890 に答える
11

int関数本体内で一度に変換されるのはなぜですか?

そうではありません。それはまだrvalueへの参照です。

名前が式に現れるとき、それは左辺値です - たまたま右辺値への参照であっても。式で必要な場合 (つまり、その値が必要な場合) は右辺値に変換できます。ただし、右辺値参照にバインドすることはできません。

あなたが言うように、別の右辺値参照にバインドするには、名前のない右辺値に明示的に変換する必要があります。std::forwardそれstd::moveを行う便利な方法です。

また、なぜstd::moveですか?

なぜそうではないのですか?これはstd::forward、引数が参照であるかどうかがわからないテンプレートを対象としています。

于 2012-09-26T17:06:11.530 に答える
9

それが「ノーネームルール」です。中barxは、名前が… x。したがって、現在は左辺値です。何かを右辺値参照として関数に渡しても、関数内の右辺値にはなりません。

なぜこのようにしなければならないのかわからない場合は、自問してみてください -返品x後は何ですか? foofoo移動は自由xです。)

于 2012-09-26T17:00:02.560 に答える