7

クラスの移動セマンティクスの実装にかなりの時間を費やしてきましたが、今はそれを使用する関数を扱っています。

さて、ヒープ上に大量のデータを持つこのオブジェクトがあります。このオブジェクトに対してCLargeOb、移動セマンティクス (コンストラクターと演算子 =) を実装しました。次のように使用するのが理想的です。

void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2)
{
    SomeOtherFunc(largeOb1); // use objects
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals
    m_largeOb2 = (CLargeOb&&)largeOb2;
}

ただし、オブジェクトを常に移動/破棄できるとは限らないため、次の 2 つの機能を追加しました。

void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2)
{
    SomeOtherFunc(largeOb1);
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = largeOb1;
    m_largeOb2 = (CLargeOb&&)largeOb2;
}

void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2)
{
    SomeOtherFunc(largeOb1);
    SomeOtherFunc(largeOb2); 
    m_largeOb1 = (CLargeOb&&)largeOb1;
    m_largeOb2 = largeOb2;
}

それは機能しますが、これらのオブジェクトを 3 つ以上パラメーターとして受け取る関数がある場合、*ss で大きな問題になることは既に推測できます...テンプレートを使用してこれを解決する賢い方法はありませんか? 「完璧な転送」?

4

1 に答える 1

15

C++03 の場合と同様に、ガイドラインは次のとおりです。コピーが必要な場合は、パラメーター リストで作成します

これにより、呼び出し元はオブジェクトの取得方法を処理できます。オブジェクトを取得するだけです。

void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) 
{ 
    SomeOtherFunc(largeOb1); // use objects 
    SomeOtherFunc(largeOb2);  
    m_largeOb1 = std::move(largeOb1); // save as members and trash the originals 
    m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast)
} 

呼び出し側:

OtherOb o;

CLargeOb x, y;
const CLargeOb z;

o.Func(x, std::move(y)); // need x for later, done with y so move it
o.Func(std::move(x), z); // done with x, necessarily copy z

これは、いくつかの特殊なオーバーロードと同じくらい効率的です。なんで?それらはコンストラクターとしてクラスに既に存在するためです。呼び出しサイトで何を呼び出すかをコンパイラーに判断させます。コンパイラーは何をすべきかを既に知っています。

于 2012-08-03T21:27:35.660 に答える