オブジェクトを保存する場合は値で受け入れ、アクセスする必要がある場合はconst参照で受け入れるという「ルール」に満足しました。このように、あなた(クラスの作成者)は、クラスの変数のユーザーをコピーするか、それを移動するかを選択しません。しかし、使用中、私はそのアドバイスの健全性についてますます確信が持てなくなりました。移動はコスト操作で均一ではありません...
struct Thing
{
std::array<int, 10000> m_BigArray;
};
class Doer
{
public:
Doer(Thing thing) : m_Thing(std::move(thing)) {}
private:
Thing m_Thing;
};
int main()
{
Thing thing;
Doer doer1(std::move(thing)); // user can decide to move 'thing'
// or
Doer doer2(thing); // user can decide to copy 'thing'
}
上記の例では、移動はコピーと同じくらい高価です。したがって、const参照を取得してオブジェクトを一度コピーする代わりに、オブジェクトを2回移動(効果的にコピー)することになります。ユーザーはあなたの議論に対して一度それを行い、あなたはあなたのメンバーに対して再びそれを行います。
これは、移動がコピーよりも大幅に安い場合でもさらに悪化します(移動するものは以下の未知のコストですが、コピーよりも安いふりをします):
struct A
{
A(Thing thing) : m_Thing(std::move(thing)) {}
Thing m_Thing;
};
struct B : A
{
B(Thing thing) : A(std::move(thing)) {}
};
struct C : B
{
C(Thing thing) : B(std::move(thing)) {}
};
struct D : C
{
D(Thing thing) : C(std::move(thing)) {}
};
ここでは、1コピーと4ムーブ、または5ムーブのいずれかになります。すべてのコンストラクターがconst参照を受け入れた場合、それは1つのコピーになります。今、私は何が高価なのか、1コピーまたは5ムーブを比較検討する必要があります。
これらの状況に対処するための最良のアドバイスは何ですか?