Recently I have been reading a lot of material on C++ right-values due to my work. In C++, right-valued is a very important concept that is crucial to understand the internal mechanisms of C++ and to implement efficient code. In this article, I will summarize 10 practical lessons about right values.
- There are two types of C++ right values: pure right values, and will-be-dead values. A right-valued reference extends the life cycle of a will-be-dead value, allowing the will-be-dead value to be used normally and not released by mistake.
- One effect of right-value references is to extend the life cycle of right values. A right-value reference extends the life cycle of a would-be-dead value, allowing the would-be-dead value to be used normally and not released by mistake.
- Temporary objects are treated as right values. Such objects are often created automatically in some expression and then used immediately. Using right-valued references to bind temporary objects allows the program to handle these objects more efficiently, avoiding unnecessary memory copy operations.
- Move constructors bind right-valued nonconstants as much as possible. This is because right-valued nonconstants can be modified, whereas right-valued constants cannot. The move constructor destroys the source object, so only right-valued nonconstants can be bound by the move constructor.
- For a right-valued object, member function calls are allowed. This is similar to left-valued objects. Note, however, that for a dying value, calling its member function may result in undefined behavior for the program if it is at the end of its life cycle.
- Right-values can be modified (which also means that they can be destroyed). Therefore, right values need to be handled with care in order to avoid problems with the program because they have been modified.
- Right values cannot be used as left values; left values can be used as right values. This is because a left value has an actual address and behaves in the same way as a right value.
- A constant left reference can be bound to a right value. Such a reference avoids the risk of modifying the right-valued object, and also extends the life cycle of the right-valued object so that it can be used normally.
- Functions that return right-valued references are bad in almost all cases. This is because returning a right-valued reference tends to cause the life cycle of the right-value to lengthen so that it can be used incorrectly. For functions that return right-valued references, it is recommended to use a value return.
- In most cases the use of is std::move in return does not make things better, instead the operation prevents the compiler from performing return value optimization.