2017-07-26 17 views
0

今日私は、このコードが動作すると期待しているので、このコードは機能しません。 私の知っているL値のコピーコンストラクタは、R値の場合は移動コンストラクタを選択する必要があります。そうでなければ、実際には何もしませんが、R値にキャストするstd::moveの目的は何ですか。私はreturn objがコピーコンストラクタを呼び出すと予想していましたが、moveを呼び出します。 コピーはここでは役に立たないと理解しますが、これはルールに関するものです。私のコピーコンストラクタが副作用を持っていて、それが私のケースです(私はそれがすべきではないことを知っていますが、技術的にはそれが可能です - 例えばstd :: cout call)。 このような動作を可能にする標準はありますか?また、どのように私はコピーを強制することができますか? cppreference(強調鉱山)からmoveコンストラクタがコピーの代わりに返されました

#include <iostream> 

class X 
{ 
public: 
    X() = default; 

    X(const X& r): i(r.i) 
    { 
     std::cout << "copy ctor" << std::endl; 
    } 

    X(const X&& r): i(r.i) 
    { 
     std::cout << "move ctor" << std::endl; 
    } 
    int i = 0; 
}; 

X foo() 
{ 
    X obj; 
    obj.i = 10; 
    return obj; 
} 

int main() 
{ 
    X x = foo(); 
} 

移動CTOR

移動CTOR

答えて

1

[返さ発現は】左辺値表現との条件の場合copy elisionが満たされているか、または満たされていることを除いて、[返された式]が関数パラメータの名前を指定します最初ののように、[返された式]がrvalue式であるように(したがって、moveコンストラクタまたはconstを参照するコピーコンストラクタを選択することができます)適切な変換が利用できない場合、lvalue [returned expression]を使用して2回目のオーバーロード解決が行われます(非constを参照するコピーコンストラクタが選択される可能性があります)。 上記のルールは、かいつまんで

(コピーの省略が同じ型を必要とする)関数の戻り値の型は[返さ式]の種類が異なる場合にも適用され、 returnは、暗黙的にそれが行ったときに、あなたが返すものを移動しようとしますセンス。最後の手段としてのみコピーされます(例えば、利用可能な移動コンストラクタはありません)。

+0

あなたが明示的に移動を要求した場合、それは暗黙のうちにコピーされてしまい、移動しないかもしれません。 – incognito

+0

説明ありがとうございます – incognito

+0

本当に@incognitoです。そのため、クラスを慎重に設計する必要があります。 – Quentin

関連する問題