The ultimate parsing of c++11 referencing temporary variables

Source: Internet
Author: User

Work encountered a reference to the issue of temporary variables, after two days of study, private thought: not only to understand the problem, but also some of their own unique ideas. Here's a simple example to dedicate your learning process and understanding to everyone, and if you have any questions, please do not hesitate to correct it. code************************* classDog{ Public:Dog(){}Virtual~Dog(){}};voidnonconstreference(Dog&Dog){//tell the dog to does something here}voidtestnonconstreference(){nonconstreference(Dog());} VS, Level4 (/w4) ************************* warning C4239:nonstandard extension used: ' Argument ': Conversion from ' dog ' to ' dog & ' *************************GCC, c++11************************* --------------Build:debug in Test (compiler:gnu GCC compiler)---------------Mingw32-g++.exe-wall-fexceptions-g-std=c++11-c G:\MyBackup\code\CodeBlock\Test\main.cpp-o obj\debug\main.og:\ mybackup\code\codeblock\test\main.cpp:in function ' void testnonconstreference () ':G:\mybackup\code\codeblock\test\main.cpp:18:29:error:invalid Initialization ofnon-const Reference of type' dog& ' from anrvalue of type' Dog 'g:\mybackup\code\codeblock\test\main.cpp:11:6: error:in passing argument 1 of ' void Nonconstreference (Dog&) ' Process terminated with status 1 (0 minute (s), 0 second (s)) 2 Error (s), 0 warning (s) (0 minute (s), 0 second (s)) Lvalue, Xvalue, Prvalue general definition ************************* First Lvalue, rvalue are for expressions Any expression can be categorized as follows: Lvalue refers to a function or object. For example:
    1. E is a pointer, then *e is Lvalue
    2. The return value of a function is an lvalue reference, and its return value is Lvalue. For example int& foo ();
Xvalue refers to an object, but unlike Lvalue, the object is about to die. Prvalue refers to a temporary object, a child object of a temporary object, or a value that is not assigned to any object. For example:
    1. The return value of a function is the usual type, and its return value is rvalue. For example, int foo ();
    2. There are no values assigned to any object. such as 5.3,true.
Lvalue, Xvalue, Prvalue distinguish ************************* Description: This part comes from C + + programming LANGUAGE 4TH Edtion. There is the properties that matter for a object when it comes to addressing, copying, and moving:
Has identity: The program have the name of, pointer to, or reference to the object so it's possible to determine if both objects a Re the same, whether the value of the object has changed, etc.
Movable: The object is moved from (i.e., we is allowed to move it value to another location and leave the object in a valid But unspecified state, rather than copying;).

It turns out this three of the four possible combinations of those the properties is needed to precisely describe the C + + Language rules (we have no need for objects that does not have the identity and
cannot be moved). Using "M for movable" and "I for have identity, ' we can represent this classification of expressions graphically:

So, a classical lvalue was something that have identity and cannot be moved (because we could examine it after a move), and A classical rvalue is anything this we are allowed to move from.

ISO IEC 14882 2011 8.5.3 ReferencesThe ISO document uses CVS to represent the const volatile modifier. And suppose we use a way to assign values: cv1 T1 dest = cv2 T2 src; for example: int src = 123;const int& dest = src; void function (const int& dest) {};function (SRC); The ISO document first gives two concepts: reference-related, reference-compatible. Given Types " CV1T1 "and" Cv2T2, "" CV1T1 "is reference-relatedTo " Cv2T2 "If
    1. T1 is the same type as T2, or
    2. T1 is a base class of T2.
CV1T1 "is reference-compatibleWith " Cv2T2 "If
    1. T1 is reference-related to T2 and
    2. CV1 is the same cv-qualification as, or greater cv-qualification than, cv2.
Description: CV1 >= cv2: const > No modifier, const volatile > Const,etc. Parse once assignment: cv1 T1 dest = cv2 T2 src; The legal use of the following 4 steps: 1. If Dest is a lvalue reference, at the same time: 1.1 If SRC is an lvalue (not a bit-filed) and Cv1 T1 is reference-compatible with Cv2 T2 ; 1.2 If T2 is a class type (class, struct, Union, etc), even if CV1 T1is notReference-compatible with Cv2 T2, as long as Cv2 T2 can be converted to an lvalue of the cv3 T3 type (SRC1), if Cv1 T1 is reference-compatible with cv3 T3; then des T fix it to SRC, or src1. 2. If Cv2 T2 SRC does not meet 1.1,1.2, then CV1 should be a lvalue reference definition that contains a const, otherwise it would be a rvalue reference. At this point if the Cv2 T2 satisfies the following conditions: 2.1 If SRC is a xvalue, a prvalue of class type, an array prvalue or a function that returns an Lvalue, and Cv1 T1 is reference-compatible with Cv2 T2 ; 2.2 If Cv2 T2 is of class type, even CV1 T1is notReference-compatible with Cv2 T2, as long as Cv2 T2 can be converted to a 2.1 specified value of the CV3 T3 type, assuming it is src1; then dest will help to SRC, or src1.     3. If Cv2 T2 SRC does not satisfy the 2.1,2.2, then the compiler creates a temporary variable for SRC. 3.1 The condition for creating this temporary variable is: CV1 T1 is reference-relatedWith Cv2 T2, and Cv1 >= cv2; 4. If Cv2 T2 SRC does not meet all of the above conditions, then CV1 T1 should be a rvalue reference. At this point, if Cv2 T2 is a lvalue, the compiler should hold the wrong. Reference matching (filtering) process ************************* ************************************** Here are some examples of **************************************------------------------------- Can be processed by rule 1-------------------------------------------------Double d = 2.0;

double& rd = D;//d, is an lvalue, and the CV1 equals CV2, 1.1 capable of handling Const double& RCD = D;//D, is an lvalue,//The CV1 >= cv2:const > No modifier, 1.1 capable of handling struct A {};
struct B:A     { operator int& ();} b;
     a& RA = b;//b, has A class type:struct;//CV1 is reference related with CV2, and Ra is the base class of the b,1.2 capable of handling const a& RCA = B;//b, has A class type, struct;//CV1 is reference related with Cv2, RA is the base class of the B;//The CV1 >= cv2:const > No modifier, 1.2 capable of handling int& ir = b ();//b (), has a class type:struct//it can converted to an lvalue of the Int&: operator int& ()//CV1 = = CV2:CV modifier is empty, 1.2 can handle ------------------------------does not conform to rule 1 and is handled by rule 2-----------------------------------------     
extern B f ();
     

Const a& RCA2 = f ();//F () The return value is a rvalue of a class type,

//The CV1 >= cv2:const > No modifier, 2.1 capable of handling
struct X {
operator B ();
operator int& ();
} x;
Const a& r = x;//x is a class-type//R and X are not reference-compatible//X returns a class type of Prvalue through operator B (), TMPBthe relationship between R and TMPB satisfies 2.1 of the conditions, 2.2 can handle the-----------------------does not conform to rule 1 and does not conform to rule 2 and is handled by rule 3--------------------------- const double& RCD2 = 2;//2, not a lvalue/xvalue/class type prvalue/function returns the left value, etc. //Create a temporary variable 2.0,3 can handle --------does not conform to rule 1, also does not conform to rule 2, does not conform to rule 3, is handled by rule 4---------------------- Double d2 = 1.0;
double&& rrd2 = d2;//Rrd2 is a rvalue reference and cannot be assigned with Lvalue. 4 able to handle  -----------------------------------------Some other examples------------------------------------------------------------- const volatile int CVI = 1;
const int& r2 = CVI;//error, in thisexample, the CV1 <= cv2, which violate the 1.1  ************************* back to our example ************************* classDog{ Public:Dog(){}Virtual~Dog(){}};void nonconstreference(Dog&Dog){//tell the dog to does something here}voidtestnonconstreference(){nonconstreference(Dog()); }nonconstreference(Dog()) Call to create a class type of prvalue on the stack. According to the ISO document, it cannot be accepted in rule 1, it can only be processed by rule 2. Rule 2 Requirementsnonconstreference(Dog&Dog)the dog & dog must be a const dog & dog. and here is obviously not, so hold the wrong.  What did the compiler do for us? Semantic Analysis ***************************** The compiler, in strict accordance with the design of the C + + language, performs a semantic check:
    1. The goal is a lvalue reference, then can not give me a rvalue.
    2. or set the target to a const lvalue reference.
If a parameter is passed in as a non-const reference, the C + + compiler thinks that the program modifies the value in the function and wants the modified value. But if you pass in a temporary variable as a non-const reference parameter, the program does not have the opportunity to continue accessing such a variable, making it meaningless to modify a temporary variable. The C + + compiler thus joins the semantic limit of temporary variables that cannot be used as non-const references, and is intended to limit the potential errors of this very compliant usage. Finish *******************************************

The ultimate parsing of c++11 referencing temporary variables

Related Article

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.