0

次のコードを検討してください。

#include <iostream>

#define P_(x) std::cout << x << std::endl

class B {
public:
    B() { P_("B::B()"); }
    B(const B&) { P_("B::B(const B&)"); }
    B(B&&) { P_("B::B(B&&)"); }
    ~B() { P_("B::~B()"); }

    B& operator=(const B&) { P_("B::op=(const B&)"); return *this; }
    B& operator=(B&& b) { P_("B::op=(B&&)"); return *this; }
};

class Foo {
public:
    void setB(const B& b) { mB = b; }
private:
    B mB;
};

B genB() {
    return B();
}

int main() {
    Foo f;
    f.setB(genB());
}

Bコピー構築が困難な型であるとします。B(関数を使用して)いくつかを生成genBし、Foo. は一時的な結果を返すためgenB、ムーブ コンストラクターが使用されることを期待します。

ただし、コードを実行すると、次の出力が得られます。

B::B()
B::B()
B::op=(const B&)
B::~B()
B::~B()

これは、2 つの B が作成されて破棄されることを明確に示していますが、2 番目はコピーであり、1 番目の移動ではありません。

可能な限り移動コンストラクターを使用するための最良の方法は何ですか?

  • std::move() をどこかで呼び出す必要がありますか?
  • B&aとa に別のオーバーロードが必要B&&ですか?
  • 私が見逃しているものは他にありますか?
4

2 に答える 2

3

setBその関数をオーバーロードできます:

class Foo {
public:
    void setB(const B& b) { mB = b; }
    void setB(B&& b) { mB = std::move(b); }
private:
    B mB;
};

または、「値渡し」の方法を使用できます。

class Foo {
public:
    void setB(B b) { mB = std::move(b); }
private:
    B mB;
};

ここで、パラメーターbは可能な場合は移動構築され、それ以外の場合はコピー構築されます。

于 2013-07-10T14:03:25.027 に答える