5

私は最近c++を使い始め、 c++11の機能を学ぶことにしました。しかし、C++ コードがどのように実行されるかは、あまり具体的でない場合があります。

以下は私のコードです。の部分でdecltype(std::move(sample)) sample2 = std::move(sample);、この行が移動コンストラクターを呼び出さない理由がわかりません。理由を説明していただけますか?

#include <iostream>

class AAA
{
   public:
      AAA() { std::cout << "default constructor" << std::endl; }
      AAA(const AAA& cs) { std::cout << "copy constructor" << std::endl; }
      AAA(AAA&& cs) { std::cout << "move constructor" << std::endl; }
      ~AAA() { std::cout << "destructor" << std::endl; }
};

int main(int argc, char* args[])
{
    AAA sample;
// ((right here))
    decltype(std::move(sample)) sample2 = std::move(sample); 
    return 0;
}

[gcc 5.4.0]を使用して[ubuntu 16.04 LTS]でコンパイルされています

元のコード: https://ide.geeksforgeeks.org/tALvLuSNbN

4

2 に答える 2

6

関数std::move<T>は を返すT &&ので、std::move(sample)それは を返しますAAA &&。これは右辺値参照であり、どちらも既に存在するオブジェクトのエイリアスであるという点で、左辺値参照(左辺値参照のような型)とよく似た動作をします。AAA &

がそれ自体で何かを動かすわけstd::moveではないことを理解することが重要です。指定された引数への右辺値参照を返すだけです。たとえば、単独ではまったく何もしません。結果が有用になるのは、結果が初期化またはオブジェクトへの代入に使用される場合のみです。std::move(foo);

たとえばauto bar = std::move(foo);、右辺値参照を返し、その参照を使用してのコンストラクターfooを呼び出します。bar

質問に答えると、std::move(sample)a が返されるのでAAA &&、問題の行は と同じAAA && sample2 = std::move(sample);です。動作は実質的に と同じAAA & sample2 = sample;です。どちらの場合も、既存のオブジェクトへの参照を初期化していて、新しいオブジェクトを構築する必要はありません。

あなたの目標がsample新しい に移行することAAAである場合、正しい行auto sample2 = std::move(sample);sample3. sample3ただし、行がすでに移動元から移動していることに注意してくださいsample

于 2018-07-16T15:37:41.507 に答える