简体   繁体   English

rvalue保证什么样的优化?

[英]What kind of optimizations does rvalue guarantee?

I want to construct an object with another using rvalue. 我想用另一个使用rvalue构造一个对象。

class BigDataClass{
public:
    BigDataClass(); //some default BigData
    BigDataClass(BigDataClass&& anotherBigData);
private:
    BigDataClass(BigDataClass& anotherBigData);

    BigDataPtr m_data;
};

So now I want to do something like: 所以现在我想做一些事情:

BigDataClass someData;
BigDataClass anotherData(std::move(someData));

So now anotherData gets rValue. 所以现在anotherData获得了rValue。 It's an eXpiring Value in fact, so as http://en.cppreference.com/w/cpp/utility/move states compiler now has an oppourtunity to optimize the initialization of anotherData with moving someData to another. 事实上,这是一个eXpiring Value,因此http://en.cppreference.com/w/cpp/utility/move状态编译器现在有机会通过将someData移动到另一个来优化anotherData的初始化。

In my opinion we can in fact get 2 different things: 在我看来,我们实际上可以得到两件不同的东西:

  1. Optimized approach: data moved. 优化方法:数据移动。 It's optimized, fast and we're happy 它经过优化,快速,我们很高兴
  2. Nonoptimized approach: data not moved. 非优化方法:数据未移动。 We have to copy data from object to another AND delete data from the first one(as far as I know after changing object to rvalue once we cannot use it, because it has got no ownership of data, that it held). 我们必须将数据从对象复制到另一个并从第一个数据中删除数据(据我所知,一旦我们无法使用它,将对象更改为rvalue,因为它没有数据的所有权,它持有)。 In fact it can be even slower than initialization with lvalue referrence due to deletion operation. 事实上,由于删除操作,它可能比使用左值参考的初始化更慢。

Can we really get so unoptimized way of data initialization? 我们真的可以获得如此未经优化的数据初始化方式吗?

You said: 你说:

So now anotherData gets rValue. 所以现在anotherData获得了rValue。 It's an eXpiring Value in fact, so as http://en.cppreference.com/w/cpp/utility/move states compiler now has an oppourtunity to optimize the initialization of anotherData with moving someData to another. 事实上它是一个eXpiring Value,因此http://en.cppreference.com/w/cpp/utility/move状态编译器现在有机会通过将someData移动到另一个来优化anotherData的初始化。

Actually, what it stated was: 实际上,它所说的是:

Code that receives such an xvalue has the opportunity to optimize away unnecessary overhead by moving data out of the argument, leaving it in a valid but unspecified state. 接收这样的xvalue的代码有机会通过将数据移出参数来优化掉不必要的开销,使其处于有效但未指定的状态。

That is, it's the code that's responsible for optimization here, not the compiler. 也就是说,这是负责优化的代码,而不是编译器。 All std::move(someData) does is cast its argument to an rvalue reference. 所有std::move(someData)都将其参数std::move(someData)转换为右值引用。 Given that BigDataClass has a constructor that takes an rvalue reference, that constructor is preferred, and that constructor will be the one that is called. 假设BigDataClass有一个带rvalue引用的构造函数,那么该构造函数是首选,并且该构造函数是被调用的构造函数。 There isn't any room for change here from the compiler's point of view. 从编译器的角度来看,这里没有任何改变的余地。 Thus the code will do whatever the BigDataClass(BigDataClass&&) constructor does. 因此代码将执行BigDataClass(BigDataClass&&)构造函数所做的任何事情。

Looks like you are confused with what is optimization and what is not. 看起来你很困惑什么是优化,什么不是。 Using move constructor (when available) is not an optimization, it is mandated by standard. 使用移动构造函数(如果可用)不是优化,它是由标准强制执行的。 It is not that the compiler has this opportunity, it has to do this. 这不是编译器有这个机会,它必须这样做。 On the other hand, copy elision is an optimization which compiler has an opportunity to perform. 另一方面,复制省略是编译器有机会执行的优化。 How relibale it is, depends on your compiler (though they are applying it pretty uniformely) and the actual function code. 它是如何重新定位的,取决于你的编译器(尽管它们非常均匀地应用它)和实际的功能代码。

You think about what the optimizer can do with move semantics. 您考虑优化器可以使用移动语义做什么。 Simply nothing itself! 什么都不是! You, the coder, has to implement the code which is the optimization compared against the constructor with a const ref. 作为编码器,您必须实现与构造函数与const ref进行比较的优化代码。

The question can go to the opposite: If the compiler already knows that you have a rvalue which is passed as const ref to a constructor, the compiler is able to do the construction as if the value is generated in the constructor itself. 问题可能恰恰相反:如果编译器已经知道你有一个rvalue作为const ref传递给构造函数,那么编译器就可以进行构造,就像在构造函数本身中生成值一样。 Copy eliding is done very often by up to date compilers. 复制删除通常由最新的编译器完成。 The question here is ( for me ) how many effort I should spend to write some rvalue reference constructions to get the same result as the compiler already builds on the fly for me. 这里的问题是(对我来说)我应该花多少努力来编写一些右值参考结构来获得与编译器已经为我建立的相同结果。

OK, in c++11 you have a lot of opportunities to handle code for forwarding and moving by your algorithms. 好的,在c ++ 11中,您有很多机会处理代码以便通过算法进行转发和移动。 And yes, some benefit can be generated. 是的,可以产生一些好处。 But I see the benefit only for templated code where I have the need to move/forward some of the parameters to (meta)template functions. 但我看到只有模板化代码的好处,我需要将一些参数移动/转发到(元)模板函数。

And on the opposite: Handling rvalue references must taken with care and the meaning of a valid but undefined state rise some questions on every user who use your interface implementation. 而恰恰相反:必须小心处理右值引用,并且有效但未定义状态的含义会对使用接口实现的每个用户产生一些问题。 See also: What can I do with a moved-from object? 另请参阅: 移动对象可以执行哪些操作?

What kind of optimizations does rvalue guarantee rvalue保证什么样的优化

Simply nothing. 什么都没有。 You have to implement it! 你必须实现它!

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

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