次のことを考慮してください。
struct X
{
Y y_;
X(const Y & y) :y_(y) {}
X(Y && y) :y_(std::move(y)) {}
};
移動セマンティクスを最大限に活用するには、2番目のコンストラクターのようなコンストラクターを定義する必要がありますか?それとも、適切な状況で自動的に処理されますか?
次のことを考慮してください。
struct X
{
Y y_;
X(const Y & y) :y_(y) {}
X(Y && y) :y_(std::move(y)) {}
};
移動セマンティクスを最大限に活用するには、2番目のコンストラクターのようなコンストラクターを定義する必要がありますか?それとも、適切な状況で自動的に処理されますか?
はい、しかしいいえ。コードは次のようになります。
struct X
{
Y y_;
X(Y y) : // either copy, move, or elide a Y
y_(std::move(y)) // and move it to the member
{}
};
デザインで「このデータの自分のコピーが必要です」*と言った場合は、引数を値で取得し、必要な場所に移動する必要があります。その値を構築する方法を決定するのはあなたの仕事ではありません。それはその値に使用できるコンストラクター次第です。そのため、それが何であれ、その選択を行い、最終結果を処理します。
*もちろん、これは関数にも当てはまります。たとえば、次のようになります。
void add_to_map(std::string x, int y) // either copy, move or elide a std::string
{
// and move it to where it needs to be
someMap.insert(std::make_pair(std::move(x), y));
}
タイプがデフォルトで構築可能でスワップ可能である場合(とにかくすべて移動します)、C++03でも適用されることに注意してください。
// C++03
struct X
{
std::string y_;
X(std::string y) // either copy or elide a std::string
{
swap(y_, y); // and "move" it to the member
}
};
これはそれほど広く行われているようには見えませんでしたが。
はい、必要です。const refはコピーのみであり、移動ではありません。