我想使用rvalue构建另一个对象。
class BigDataClass{
public:
BigDataClass(); //some default BigData
BigDataClass(BigDataClass&& anotherBigData);
private:
BigDataClass(BigDataClass& anotherBigData);
BigDataPtr m_data;
};
所以现在我想做点什么:
BigDataClass someData;
BigDataClass anotherData(std::move(someData));
所以现在anotherData获得了rValue。事实上,这是一个eXpiring Value,因此http://en.cppreference.com/w/cpp/utility/move现在称为编译器 有机会通过移动来优化anotherData的初始化 someData到另一个。
在我看来,我们实际上可以得到两件不同的东西:
我们真的可以获得如此未经优化的数据初始化方式吗?
答案 0 :(得分:10)
你说:
所以现在anotherData获得了rValue。它实际上是一个有效的值,因此http://en.cppreference.com/w/cpp/utility/move状态编译器现在有机会通过将someData移动到另一个来优化anotherData的初始化。
实际上,它所说的是:
接收到这样一个xvalue的代码有机会通过将数据移出参数来优化掉不必要的开销,使其处于有效但未指定的状态。
也就是说,它是负责优化的代码,而不是编译器。所有std::move(someData)
都将其参数转换为右值引用。假设BigDataClass
有一个带右值引用的构造函数,那么该构造函数是首选,而构造函数将成为被调用的构造函数。从编译器的角度来看,这里没有任何改变的余地。因此代码将执行BigDataClass(BigDataClass&&)
构造函数所做的任何事情。
答案 1 :(得分:5)
看起来你很困惑什么是优化,什么不是。使用移动构造函数(如果可用)不是优化,它是由标准强制执行的。这不是编译器有这个机会,它必须这样做。 另一方面,复制省略是编译器有机会执行的优化。它是如何重新定位的,取决于你的编译器(虽然它们非常均匀地应用它)和实际的功能代码。
答案 2 :(得分:1)
您考虑优化器可以使用移动语义做什么。什么都不是!作为编码器,您必须实现与构造函数进行优化的代码,并使用const ref。
问题可能恰恰相反: 如果编译器已经知道你有一个作为const ref传递给构造函数的rvalue,那么编译器就可以进行构造,就像在构造函数本身中生成值一样。复制删除通常由最新的编译器完成。这里的问题是(对我来说)我应该花多少努力来编写一些右值参考结构,以获得与编译器已经为我实时构建的结果相同的结果。
好的,在c ++ 11中,您有很多机会处理代码以便通过算法进行转发和移动。是的,可以产生一些好处。但我看到只有模板化代码的好处,我需要将一些参数移动/转发到(元)模板函数。
恰恰相反:处理右值引用必须小心谨慎,有效但未定义状态的含义会对使用接口实现的每个用户产生一些问题。另见:What can I do with a moved-from object?
rvalue保证什么样的优化
一无所获。你必须实现它!