General features: Move / rvalue references

code

Lvalue vs Rvalue

L stands for left side. It will be located on the left side of expression, for example some variable.
R stands for right side. This will be located on the right side of expression and it should not be found on left side, the specimen for it is a constant.

=> a, b are lvalues. They have a memory address that we can point to.

 

=> a * b is an rvalue. It doesn’t have a memory address and its value is lost after the sequence point.

 

Syntax

&& indicates an “rvalue reference”.

An rvalue reference can bind to an rvalue (but not to an lvalue)

 

Move semantics

Move semantics allows an object, under certain conditions, to take ownership of some other object’s external resources. This is important in two ways:

  • Turning expensive copies into cheap moves.
  • Implementing safe “move-only” types; that is, types for which copying does not make sense, but moving does. Examples include locks, file handles, and smart pointers with unique ownership semantics.

 

Move constructor / assignment operator

A move operation is intended to be a destructive copy.

Instead of copying data over, move implemented correctly:

  • Assigns the address of source pointers to destination pointers
  • Copies over primitive values
  • Sets source pointers to nullptr
  • Either ignores source primitive values or sets them to 0
  • Since all pointers in the source are set to nullptr, they are not destructed.

 

std::move

std::move takes as an argument any type and returns an rvalue reference of that type.

  • Does not trigger copy constructor

This is very useful for:

  • Implementing move constructors
  • Implementing swap operations

 

 

move(x) means “you can treat x as an rvalue”.

 

std::move_if_noexcept

Returns std::move(x) or x, depending on exception guarantees. => Use whether move or copy construction (unless copy ctor is N/A)

 

 

Compiler default generate

As is the case with the copy operations, the move operations aren’t generated if you declare them yourself.

  • move operations won’t be generated for any class that explicitly declares a copy operation
  • Declaring a move operation (construction or assignment) in a class causes compilers to disable the copy operations.

 

How to call a function that accepts a moved object?

 

Perfect forwarding

Perfect forwarding makes it possible to write function templates that take arbitrary arguments and forward them to other functions such that the target functions receive exactly the same arguments as were passed to the forwarding functions.

Leave a comment

Your email address will not be published.