简体   繁体   English

获取要使用的移动构造函数/赋值运算符

[英]Getting the move constructor/assignment operator to be used

Consider the following code: 考虑以下代码:

#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());
}

Suppose B is a type that is difficult to copy-construct. 假设B是难以复制构造的类型。 I'd like to generate some B (with the function genB ) and store it in a Foo . 我想生成一些B (使用genB函数)并将其存储在Foo Since genB returns a temporary result, I'd expect that a move constructor would be used. 由于genB返回一个临时结果,所以我希望将使用move构造函数。

However, when I run the code, I get this output: 但是,当我运行代码时,得到以下输出:

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

This clearly shows that two B's get created and destroyed, but that the second is a copy, and not a move of the first. 这清楚地显示了两个B的创建和销毁,但是第二个是副本,而不是第一个的举动。

What is the best way to get move constructors used whenever possible? 尽可能使用移动构造函数的最佳方法是什么?

  • Do I need to call std::move() somewhere? 我需要在某处调用std :: move()吗?
  • Do I need a separate overload for a B& and a B&& ? B&B&&是否需要单独的重载?
  • Is there something else entirely that I'm missing? 还有我完全想不到的东西吗?

You could overload that setB function: 您可以重载该setB函数:

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

Or, you can use the "pass by value" way: 或者,您可以使用“按值传递”方式:

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

Here, the parameter b will be move constructed when possible or copy constructed otherwise. 在这里,参数b将在可能的情况下进行移动构造,否则将进行复制构造。

The first B instance is the one created when creating your Foo instance : 第一个B实例是创建Foo实例时创建的:

Foo f;

This is because your Foo class has a B member called mB . 这是因为您的Foo类具有一个称为mBB成员。

The second B instance is the one created by the genB() call. 第二个B实例是由genB()调用创建的实例。

The assignment operator is called because of the assignment you perform in the Foo::setB function : 之所以调用赋值运算符,是因为您在Foo::setB函数中执行了赋值:

mB = b;

Nowhere is there a chance to use a copy or move constructor. 没有地方可以使用复制或移动构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM