2012-11-27 13 views
9

According to another answer、それを参照する式がxvalue式である場合、rvalue参照は一時的な存続期間を延長しません。大丈夫ですrvalue参照での一時的な存続期間の延長

int main() 
{ 
    std::string&& danger = std::move(get_string()); // dangling reference ! 
    return 0; 
} 

std::moveは右辺値参照を返すので、それを呼び出すの発現ははxValueので、ダングリング参照した次の結果です。 std::moveはここで意味をなさない。それは既に価値である。

ここで私は空白を描いています。 xvalue式を引数として渡すこととはどのように違いますか?std::moveとrvalue参照の完全な標準使用ですか?

void foo(const std::string& val); 
// More efficient foo for temporaries: 
void foo(std::string&& val); 

int main() 
{ 
    std::string s; 
    foo(std::move(s)); // Give up s for efficiency 
    return 0; 
} 

かかわらず、それはprvalueかはxValueであるかどうかの一時的なの寿命を延長します右辺値参照の引数のための特別なルールがありますか?あるいは、既に値があったものを渡したので、std::move呼び出し式はxvalueだけですか?とにかくrvalue参照を返すので、私はそうは考えていません。これはxvalueです。私はここで混乱している。私は何か愚かなことを逃していると思う。

+0

無関係:関数 'foo'がいずれかの方法でコピーまたは移動しようとしている場合は、値を引数として引数を取り、コンパイラにコピーまたは移動させます。 –

+0

最初の例の注意: 'std :: move(get_string())'は一時的な式ではありません。一時的な表現は 'get_string()'でしたが、それをキャストしました。したがって、参照への一時的な式のバインディングに関するルールは適用されなくなりました。 –

答えて

7

ここで寿命を延ばす必要はありません。問題のオブジェクトは、fooの末尾のmainの末尾まで続きます。

+0

確かに...与えられたコードには一時的なものはありません。 – Mankarse

+4

ああ私の神。睡眠が必要だ。 –

8

第2の例では、一時的な参照を渡していないので、変数sへの参照を渡しています。これは、末尾がmain()まで続きます。

(たとえばfoo(std::move(get_string()));)の場合、一時的な有効期間は、関数が返された後の完全な式の最後まで続きます。したがって、foo内で使用することは非常に安全です。 fooがその引数への参照/ポインタを格納していて、後でそれを使用しようとすると、危険性があります。

+1

しかし、rvaluesのアドレスを取ることは違法です。 – user1095108

+4

@ user1095108しかし、 'val'は' foo(std :: string && val) '関数の本体内のrvalueではありません。これは型 "rvalue reference"の左辺値です。 's'の存続期間が終わるまで、そのアドレスを使用し、そのアドレスを使用することは完全に合法です。 – Oktalist