C++11 右辺値と return 文による移動セマンティクス 質問する

C++11 右辺値と return 文による移動セマンティクス 質問する

私は C++11 の右辺値参照と移動セマンティクスを理解しようとしています。

これらの例の違いは何ですか? また、ベクターコピーを行わないのはどれですか?

最初の例:

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

std::vector<int> &&rval_ref = return_vector();

2番目の例:

std::vector<int>&& return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();

3番目の例:

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();

ベストアンサー1

最初の例

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

std::vector<int> &&rval_ref = return_vector();

最初の例は、 によってキャッチされる一時オブジェクトを返しますrval_ref。その一時オブジェクトの有効期間は定義を超えて延長されrval_ref、値によってキャッチしたかのように使用できます。これは次の例と非常によく似ています。

const std::vector<int>& rval_ref = return_vector();

ただし、私の書き直しでは、明らかにrval_ref非 const 方式で使用することはできません。

2番目の例

std::vector<int>&& return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();

2 番目の例では、実行時エラーが発生しています。関数内ではrval_ref、破棄されたオブジェクトへの参照が保持されますtmp。運が良ければ、このコードはすぐにクラッシュします。

3番目の例

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp);
}

std::vector<int> &&rval_ref = return_vector();

3 番目の例は、最初の例とほぼ同等です。on はstd::move不要tmpであり、戻り値の最適化を妨げるため、実際にはパフォーマンスが低下する可能性があります。

実行していることをコード化する最良の方法は次のとおりです。

ベストプラクティス

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return tmp;
}

std::vector<int> rval_ref = return_vector();

つまり、C++03の場合と同じです。tmp戻り値ステートメントでは暗黙的に右辺値として扱われます。戻り値最適化(コピーなし、移動なし)によって返されるか、コンパイラがRVOを実行できないと判断した場合は、ベクターの移動コンストラクタを使用して戻り値を返しますRVO が実行されず、返される型に移動コンストラクターがない場合のみ、戻り値にコピー コンストラクターが使用されます。

おすすめ記事