They say认为Rvalue的成员也是Rvalues -这很有道理。所以,在我对Rvalue的理解中,这要么是一个特定于VC++的bug,要么是一个bug。
拿着这个玩具代码:
#include <vector>
#include <iostream>
using namespace std;
struct MyTypeInner
{
MyTypeInner() {};
~MyTypeInner() { cout << "mt2 dtor" << endl; }
MyTypeInner(const MyTypeInner& other) { cout << "mt2 copy ctor" << endl; }
MyTypeInner(MyTypeInner&& other) { cout << "mt2 move ctor" << endl; }
const MyTypeInner& operator = (const MyTypeInner& other)
{
cout << "mt2 copy =" << endl; return *this;
}
const MyTypeInner& operator = (MyTypeInner&& other)
{
cout << "mt2 move =" << endl; return *this;
}
};
struct MyTypeOuter
{
MyTypeInner mt2;
MyTypeOuter() {};
~MyTypeOuter() { cout << "mt1 dtor" << endl; }
MyTypeOuter(const MyTypeOuter& other) { cout << "mt1 copy ctor" << endl; mt2 = other.mt2; }
MyTypeOuter(MyTypeOuter&& other) { cout << "mt1 move ctor" << endl; mt2 = other.mt2; }
const MyTypeOuter& operator = (const MyTypeOuter& other)
{
cout << "mt1 copy =" << endl; mt2 = other.mt2; return *this;
}
const MyTypeOuter& operator = (MyTypeOuter&& other)
{
cout << "mt1 move =" << endl; mt2 = other.mt2; return *this;
}
};
MyTypeOuter func() { MyTypeOuter mt; return mt; }
int _tmain()
{
MyTypeOuter mt = func();
return 0;
}该代码输出:
mt1移动式电机 mt2拷贝= mt1 dtor mt2 dtor
也就是说,MyType外层的移动ctor调用MyTypeInner的副本,而不是move。如果我将代码修改为:
MyTypeOuter(MyTypeOuter&& other)
{ cout << "mt1 move ctor" << endl; mt2 = std::move(other.mt2); }产出与预期相符:
mt1移动式电机 mt2移动= mt1 dtor mt2 dtor
VC++ (2010年和2013年)似乎不尊重这部分标准。还是我漏掉了什么?
发布于 2014-08-06 06:39:44
rvalue的成员是否是rvalue不是这里的问题,因为您正在处理赋值运算符中的lvalue。
在这个移动赋值操作符中,
const MyTypeOuter& operator = (MyTypeOuter&& other)
{
cout << "mt1 move =" << endl;
mt2 = other.mt2;
return *this;
}other是一个lvalue (因为它有一个名称),因此other.mt2也是。当您说mt2 = other.mt2时,您只能调用标准赋值操作符。
为了调用移动构造函数,您需要使other.mt2看起来像一个rvalue,这就是std::move实现的目标:
const MyTypeOuter& operator = (MyTypeOuter&& other)
{
cout << "mt1 move =" << endl;
mt2 = std::move(other.mt2);
return *this;
}https://stackoverflow.com/questions/25153387
复制相似问题