2016-12-12 26 views
2

もう一度これについてもう一度、しかし、関連する質問は私の質問に答えることはありません。移動コンストラクタのないオブジェクトを移動

標準はかなり明確です:

12.8コピーとクラスオブジェクトを移動、
§9
クラスXの定義は明示的に移動コンストラクタを宣言していない場合は、1が暗黙的に宣言されます
- Xがユーザ宣言コピーコンストラクタを持たない場合、
- Xにユーザ宣言されたコピー代入演算子がありません。
- Xにはユーザ宣言されたmoがありません
- Xにユーザーが宣言したデストラクタがありません。
- 移動コンストラクタは暗黙的に削除されているとは定義されていません。
[注意:移動コンストラクタが暗黙的に宣言されていないか、明示的に指定されていない場合、移動コンストラクタを呼び出す式は代わりにコピーコンストラクタを呼び出す可能性があります。 - エンドノート]

に(私はコピーにべきフォールバックを動かすことを、知っていましたが)ので、最後に「注意」に気付い前に、私はコンパイルが失敗するコードのこの作品を期待:

#include <iostream> 
using std::cout; 
class c 
{ 
public: 
    c() { cout << "c::c()\n"; } 
    c(std::initializer_list<int>) { cout << "c::c(std::initializer_list)\n"; }; 

    c(const c&) { cout << "c::c(const c&)\n"; } 
    c& operator=(const c&) { cout << "c& c::operator=(const c&)\n"; return *this; } 

    ~c() { cout << "c::~c()\n"; } 

    void f() {} 
}; 

void f(c&& cr) { cout << "f()\n"; cr.f(); } 

int main() 
{ 
    c x; 
    f(std::move(x)); 

    return 0; 
} 

は、それから端部にメモを見たが、私は、まだ驚いたことを出力する上記のコード:

C :: C()
F()
c ::〜c()

「不足している」c::c(const c&)に注意してください。次に、私は

c(c&&) = delete; 
c& operator=(c&&) = delete; 

を追加しました。結果は変わりません。

私はここで何が欠けていますか?


$ g++ --version 
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609 

コンパイラフラグ:-s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG

+4

'cr'は、どのコンストラクタでもまだ消費されていないr値**参照**です。 –

+0

@ W.F。 - オハイオ州私、答えとして投稿してください。あなたはひどく正しいです。 –

+0

これはノップ質問です。XD – Stargateur

答えて

6

例のcrのパラメータは、r値の参照です。ここでは参照語が重要です。これは、C++ 11がゲームになる前に、コンストラクタを呼び出さないという意味で、私たちがC++から知っている平面の古いリファレンスと幾分似ています...あなたが渡すオブジェクトを単に指し示しているだけです。 ..

移動コンストラクタを呼び出す(または他のスワップを実行する)ために参照を使用するには、参照をさらに転送する必要があります。

void f(c&& cr) { 
    c cr2(std::move(cr)); 
} 
6

オブジェクトを移動しませんでした。

std::moveは実際には何も動かさないのでかなり混乱しています。移動コンストラクタまたは移動代入演算子だけがオブジェクトを移動することができます。std::moveは、r値参照(&&)にl値参照(&)をキャストします。

移動コンストラクタまたは移動代入演算子は、r値参照(&&)にバインドしてオブジェクトの内容を盗むことができます。

+0

これは本当にいい説明です。これは完全に受け入れられた答えを補完します。 –

関連する問題