2016-10-14 8 views
3

を戻しつつ:それがreturnWrapobjに機能WrapperOfGetObjの誤差を与えるコンパイルさ右辺値参照挙動以下のコードでは、関数から

class Myclass 
{  
public: 
    Myclass() = default; 
    ~Myclass() = default; 

    Myclass(Myclass&&) = default; 
    Myclass& operator=(Myclass&&) = default; 

    Myclass(const Myclass&) = delete;  
    Myclass& operator=(const Myclass&) = delete; 
}; 

Myclass GetObj() 
{ 
    Myclass obj;  
    return obj; 
} 

Myclass WrapperOfGetObj() 
{ 
    Myclass&& Wrapobj = GetObj(); 

    return Wrapobj; 
} 

int main() 
{ 
    return 0; 
} 

。エラーがある

'のMyClass :: MyClassの(のconst MyClassの&)':それはdeletedコピーコンストラクタを呼び出すようにしようとしていることを意味削除機能

に参照しよう。私が知っているようにWrapobjは左辺値であり、それが返されるとき、その動作はreturnの時に移動コンストラクタを呼び出すGetObj方法すなわちでobjと同じでなければなりません。 なぜコピーコンストラクタを探しているのですか?私はここで何が欠けていますか?

+0

明示的にrvalueを作成するには 'std :: move()'を使う必要があります。 – SingerOfTheFall

答えて

6

Wrapobjはオブジェクトではなくリファレンスであるため、暗黙的に移動します(つまり、返された左辺値を右辺値として扱う) - この場合は適用されません([class.copy]/32 )。

あなたは、書面によってこの問題を解決できます。代わりに、現在の

Myclass Wrapobj = GetObj(); 

を:

Myclass&& Wrapobj = GetObj(); 

または明示的にstd::move()ことで、それを返すときWrapobjをする。私は個人的に最初の選択肢に行くことをお勧めしたいと思います。

+0

[this](http://stackoverflow.com/questions/1116641/is-returning-by-rvalue-reference-more-efficient)は、このトピックのための良い追加読書かもしれません。 – krzaq

+1

式 'Wrapobj'は' MyClass'型の左辺値です。式は参照型を持たない([expr]/5調整の後)。問題は、暗黙の移動が自動ストレージ期間([class.copy]/32)のオブジェクトにのみ適用され、参照はオブジェクトではないということです。さらに、[CWG 1579](http://wg21.link/CWG1579)以降、 "return文の名前付き左辺値は、その型が関数の戻り値と異なる場合、コンパイラによって右辺値として扱われません" 。 –

+0

@ T.C .:標準で明確になっていますか?私がより活発になった日の前に、私はそれを確信していましたが、それはおそらく解釈に至ったと考えました(Scottのブログ記事を参照)(http://scottmeyers.blogspot.cz/2015/02/expressions -can-have-reference-type.html))。最終的な言葉はありますか?とにかく私はそれをより正確に言い換えようとします。 –

関連する問題