[英]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? 尽可能使用移动构造函数的最佳方法是什么?
B&
and a B&&
? B&
和B&&
是否需要单独的重载? 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
类具有一个称为mB
的B
成员。
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.