C++11理解(三)の右値参照
3985 ワード
右値参照とmoveの意味
C++03以前の基準では、一時オブジェクト(右値「R-values」と呼ばれ、付与演算子の右に位置する)は変更できません.Cでも同様です(const T&と区別できないとみなされます).一時的なオブジェクトは、場合によっては変更されますが、有用な脆弱性と見なされます.
C++11は、T&&&&とマークされた右値参照(R-value reference)と呼ばれる新しい非常数参照(reference)タイプを追加します.右の値で参照される一時オブジェクトは、moveの意味を許可するために、一時オブジェクトが初期化された後に変更できます.
C++03の性能が長期にわたって非難されている1つは、時間がかかり、不要な深いコピーである.深度コピーは、オブジェクトが値伝達されている場合に発生します.例えば、std::vectorは、内部にC-style配列が保存されたパッケージであり、std::vectorの一時オブジェクトが構築されたり、関数から返されたりした場合、新しいstd::vectorを生成し、その一時オブジェクトのすべてのデータを再作成することによってのみ格納することができる.一時オブジェクトとそのメモリは破壊されます.(議論の便宜上、ここでは戻り値最適化を無視)
C++11では、std::vectorの「moveコンストラクション関数」のあるvectorの右値への参照は、内部のC-style配列のポインタを単純に右値から新しいvectorにコピーし、空の右値を残すことができます.この操作は配列のレプリケーションを必要とせず、空の一時オブジェクトのプロファイルもメモリを破壊しません.vector一時オブジェクトを返す関数はstd::vector&&&を明示的に返す必要はありません.vectorにmoveコンストラクション関数がない場合、const std::vector&の通常の形式でレプリケーションコンストラクション関数が呼び出されます.moveコンストラクション関数がある場合は、moveコンストラクション関数が呼び出され、メモリ構成が大幅に不要になります.
セキュリティの理由に基づいて、名前付きパラメータは、このように宣言されても右の値として認定されません.右の値を取得するにはstd::move()を使用する必要があります.
右値参照の用語特性および左値参照(L-value references;regular references)に対するいくつかの用語修正のため、右値参照は開発者に完璧な転送(perfect function forwarding)を提供することを可能にする.この能力は、変長パラメータテンプレートと組み合わせると、関数テンプレートがこれらの特定の引数を受け入れる他の関数に引数を完璧に転送することを可能にする.最大の用途は,構造関数パラメータを転送し,これらの特定の引数のために正確な構築式を自動的に呼び出すことができるファクトリ関数(factory function)を作成することである.
C++03以前の基準では、一時オブジェクト(右値「R-values」と呼ばれ、付与演算子の右に位置する)は変更できません.Cでも同様です(const T&と区別できないとみなされます).一時的なオブジェクトは、場合によっては変更されますが、有用な脆弱性と見なされます.
C++11は、T&&&&とマークされた右値参照(R-value reference)と呼ばれる新しい非常数参照(reference)タイプを追加します.右の値で参照される一時オブジェクトは、moveの意味を許可するために、一時オブジェクトが初期化された後に変更できます.
C++03の性能が長期にわたって非難されている1つは、時間がかかり、不要な深いコピーである.深度コピーは、オブジェクトが値伝達されている場合に発生します.例えば、std::vector
C++11では、std::vectorの「moveコンストラクション関数」のあるvectorの右値への参照は、内部のC-style配列のポインタを単純に右値から新しいvectorにコピーし、空の右値を残すことができます.この操作は配列のレプリケーションを必要とせず、空の一時オブジェクトのプロファイルもメモリを破壊しません.vector一時オブジェクトを返す関数はstd::vector
セキュリティの理由に基づいて、名前付きパラメータは、このように宣言されても右の値として認定されません.右の値を取得するにはstd::move
bool is_r_value(int &&) { return true; }
bool is_r_value(const int &) { return false; }
void test(int && i)
{
is_r_value(i); // i , 。
is_r_value(std::move<int&>(i)); // std::move<T>() 。
}
右値参照の用語特性および左値参照(L-value references;regular references)に対するいくつかの用語修正のため、右値参照は開発者に完璧な転送(perfect function forwarding)を提供することを可能にする.この能力は、変長パラメータテンプレートと組み合わせると、関数テンプレートがこれらの特定の引数を受け入れる他の関数に引数を完璧に転送することを可能にする.最大の用途は,構造関数パラメータを転送し,これらの特定の引数のために正確な構築式を自動的に呼び出すことができるファクトリ関数(factory function)を作成することである.