Rvalue reference and move semantics in c++11

Source: Internet
Author: User

Catalogue
      1. Lvalue, rvalue, lvalue Reference, rvalue reference
      2. Rvalue reference and consolidated reference
      3. Use rvalue reference, avoid deep copy, optimize program performance
      4. std::move () move semantics
      5. std::forward () Perfect forwarding
      6. Emplace_back in container ()

C++11 adds a new type called Rvalue reference (R-value Reference), labeled T&&, and rvalue reference combined with Std::move can be a good optimizer for optimizing program efficiency .

1. Lvalue, rvalue, lvalue Reference, rvalue reference

The lvalue is named, corresponds to a certain area of memory, can be accessed, the right value is not named, does not correspond to the memory domain, it is inaccessible, and the temporary pair is the right value. There is an easy way to differentiate the left and right properties of an expression: an lvalue if the expression can be used with the & character, or an rvalue value. An lvalue reference is a reference to an lvalue, and an rvalue reference is a reference to a right-hand value. There is only an lvalue reference before c++11, a reference to a constant is illegal, and an rvalue reference is introduced in c++11.

1 Const int 1 ; 2 int 1; // Error 3 int 1 // && reference to Rvalue
2. Rvalue references and uniform references

"t&&" has two different meanings. One of course is the rvalue reference, which shows what you expect: they bind only to the right value, and their main job is to identify the objects that can be moved. Another implication of "t&&" is that it is both an rvalue reference and an lvalue reference, called a uniform reference. Such references look like rvalue references (that is, t&&) in your code, but they can behave like lvalue references. Their dual nature makes it possible to bind to either an rvalue (like an rvalue reference) or to an lvalue (like an lvalue reference). Uniform references appear in two scenarios, the most common is the parameters of the function template, the second scene is auto fame, and the two scenarios in common are the emergence of type deduction. In template F, the type of param is deduced, the VAR2 declaration, the type of VAR2 is also deduced, if you want to know more about &&, you can refer to scott-meyers this article: http://isocpp.org/blog/2012/ 11/universal-references-in-c11-scott-meyers

1 voidF (widget&& param);//rvalue Reference2widget&& var1 = Widget ();//rvalue Reference3Template<typename t>4 voidF (std::vector<t>&& param);//rvalue Reference5Template<typename t>6 voidF (t&& param);//Unified Referencing7auto&& var2 = var1;//Unified Referencing
3. Rvalue reference, avoid deep copy

rvalue references are used to support the transfer semantics. Transfer semantics can move resources (heaps, system objects, and so on) from one object to another, reducing the creation, copying, and destruction of unnecessary temporary objects, which can significantly improve the performance of C + + applications. Eliminates the performance impact of maintenance (creation and destruction) of temporary objects. The copy constructor and copy assignment operators are implemented as examples of a simple string class. The operation of the call copy constructor and the copy assignment operator are implemented. MyString ("Hello") and MyString ("World") are temporary objects, which are right values. Although they are temporary, the program still invokes copy construction and copy assignment, resulting in meaningless resource requests and actions released. If you can directly use the resources that the temporary object has already requested, you can save resources and save time on resource requests and releases. This is precisely the purpose of defining the transfer semantics.

#include <iostream>#include<cstring>#include<vector>using namespacestd;classMyString {Private:    Char*_data; Public:    //default constructorMyString (): _data (New Char[1]) {        *_data =' /'; Std::cout<<"default constructor"<<Std::endl; } MyString (Const Char*str): _data (New Char[Strlen (str) +1]) {std::cout<<"Constructor"<<Std::endl;    strcpy (_data, str); }    //copy ConstructorMyString (Constmystring&RHS): _data (New Char[Rhs.size () +1]) {std::cout<<"copy Constructor"<<Endl; strcpy ( This-_data, Rhs.c_str ()); } MyString (MyString&&RHS) {Std::cout<<"Move copy Constructor"<<Std::endl;  This->_data =Rhs._data; Rhs._data=nullptr; } MyString&operator= (mystring&&RHS) {Std::cout<<"Move Assign"<<Std::endl; if( This->_data! =rhs._data) {             This->_data =Rhs._data; Rhs._data=nullptr; }        return* This; }    ~MyString () {Delete[] _data; }    //Assignmystring&operator=(Constmystring&RHS) {Std::cout<<"Assign"<<Std::endl; if( This->_data = =rhs._data) {            return* This; }        Delete[] This-_data;  This->_data =New Char[Rhs.size () +1]; strcpy ( This-_data, Rhs._data); return* This; }    BOOL operator==(Constmystring&RHS) {        if(strcmp ( This->_data, rhs._data) = =0) {            return true; } Else {            return false; }    }    Char operator[] (size_t index) {if(Index >=strlen (_data)) {            return '0'; } Else {            return_data[index]; }} friend MyStringoperator+(Constmystring& LHS,Constmystring&RHS)        {MyString str; Str._data=New Char[Lhs.size () + rhs.size () +1];        strcpy (Str._data, lhs._data);        strcat (Str._data, rhs._data); returnstr; } Friend Ostream&operator<< (Ostream & out,Constmystring&str) {         out<<Str._data; return  out; } size_t size ()Const {        returnstrlen (_data); }    Const Char* C_STR ()Const {        return_data; }};intMain () {MyString str1 ("Hello");//ConstructorMyString str2 (STR1);//copy ConstructorMyString STR3= MyString ("ABC");//ConstructorMyString STR4 = Std::move (MyString ("ABA"));//constructor,move copy constructor;str2= Std::move (STR3);//Move AssignSTR2 = MyString ("ABC");//Constructor,move AssignVector<MyString>v; V.push_back (MyString (" World"));//constructor,move copy constructor;    return 0;}
4.std::move () move semantics

Std::move is the transfer of the State or ownership of an object from one object to another, except for a transfer, no memory relocation, or a memory copy. This move semantics is useful, for example, if we have pointers or dynamic arrays in an object, we do not need to copy these resources when assigning or copying objects. Before c++11, our copy constructors and assignment functions might be defined like this: Suppose there is a resource m_ptr within a object;

a& A::operator= (const a& RHS) {//  destroy M_ptr point to the resource //  Copy the resource referred to by rhs.m_ptr and make m_ptr point to it }

The above procedure is feasible, but the more efficient way is to exchange the resource pointers in a and temporary objects directly, and then let the temporary object's destructor destroy the original resources that A has. In other words, when the right side of the assignment operator is rvalue, we want the assignment operator to be defined as follows:

a& A::operator= (const a&& RHS) {    //  transfer only the owner of the resource, Change the owner of the resource to the assigned person }

This is called the move semantics. Take another example, assuming that a temporary container is large and assigned to another container.

{    std::list< std::string > tokens;   Omit initialization ...    std::list< std::string > t = tokens;} Std::list< std::string > tokens;std::list< std::string > t = std:: Move (tokens);
5.std::forword () Perfect forwarding

The rvalue reference type is independent of the value, and an rvalue reference parameter is used as the function's formal parameter, and it becomes an lvalue when the parameter is forwarded inside the function, not its original type. Therefore, we need a way to forward to another function according to the original type of the parameter, which is called perfect forwarding. The so-called Perfect forwarding (perfect forwarding) means that in a function template, parameters are passed to another function called in the function template, exactly according to the type of the template's parameters. The c++11 provides a function Std::forward, which is forwarded for forwarding, and it is forwarded by the type of the parameter, regardless of whether the parameter type is an undefined reference type of t&& or an explicit lvalue reference or rvalue reference.

Template<typename t>void print (t& T) {    "lvalue" << Std::endl;} Template<typename t>void print (t&& T) {    "rvalue " << Std::endl;} Template<typename t>void testforward (t && t) {    print (t);    Print (Std::forward<T>(T));    Print (Std::move (t));}
6. Emplace_back of Members

Most containers in c++11 add a Emplace_back member function, which is defined in the vector:

template< class ... Args >
void Emplace_back (Args&& .... Args);

The args&& here is an undetermined reference type, so it can receive lvalue references and rvalue references, and its interior is also called the Std::forward implementation for perfect forwarding. So if we need to add an rvalue, temporary variable to the container, using Emplace_back can improve performance.

Reference:

    • Article 24: Distinguishing between uniform and rvalue references

    • (original) c++11 to improve our program's rvalue reference

Rvalue reference and move semantics in c++11

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.