[英]Why move ctor is not called in this case?
#include <iostream>
using namespace std;
class Test {
public:
Test(string value){
cout<<"Ctor "<<value<<endl;
_val=value;
}
Test( Test&& mv): _val(mv._val)
{
mv._val=string();
cout<<"Mv constructor"<<endl;
}
string& get()
{
return this->_val;
}
private:
string _val;
};
void print(Test&& t)
{
cout<<"Stampa val is "<<t.get()<<endl;
}
int main()
{
Test a{"ciao"};
print(move(a));
cout<<"Val of a is "<<a.get()<<endl;
print(Test("test"));
return 0;
}
output 是(将行号添加到标准输出):
曹操
Stampa val is ciao
val 是 ciao
测试
Stampa val 是测试
为什么在 main 的第 2 行没有调用 mv 语义? 我可能会在第四行理解有一个优化,所以只调用了构造函数,但是我无法解释第一步。 有任何想法吗?
std::move
只是将参数转换为右值(可以稍后移动),它本身不执行移动操作。 转换后的右值绑定到引用参数t
,因此在这种情况下不会调用移动构造函数。
std::move 用于指示一个 object t 可能被“移出”,即允许将资源从 t 有效转移到另一个 object。
特别是,std::move 产生一个 xvalue 表达式来标识它的参数 t。 它完全等同于将 static_cast 转换为右值引用类型。
通常调用移动构造函数来初始化 object,它不会在引用绑定中调用(对于左值引用也是如此)。 如果您更改要按值传递的参数,则将使用移动构造函数(初始化参数)。 例如
void print(Test t)
{
cout<<"Stampa val is "<<t.get()<<endl;
}
顺便说一句:即使更改为按值传递print(Test("test"));
由于复制省略,不会调用移动构造函数。
BTW2:在移动构造函数中,最好根据std::string
提供的移动操作移动初始化数据成员val
。 例如
Test( Test&& mv): _val(std::move(mv._val))
{
cout<<"Mv constructor"<<endl;
}
您的代码中只有两个Test
对象,而不是更多。
int main()
{
Test a{"ciao"}; // here
print(move(a));
cout<<"Val of a is "<<a.get()<<endl;
print(Test("test")); // and here
}
第二个还通过Test(string)
构造函数构造 object。 std::move
不构造 object,它只是对右值引用的强制转换。 将该右值引用传递给print
也不需要构造另一个Test
。 如果要调用构造函数,则必须实际构造一个实例,例如:
auto t = Test( std::move(a) ); // calls Test(Test&&)
auto t2 = Test( Test("move me") ); // calls Test(string) then Test(Test&&)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.