C++98 the concept of lvalue and rvalue, but the general programmer does not need to understand too deeply, because for c++98, the division of left and right values is generally of little use, but to the C++11, its importance began to appear.
The C++98 standard expressly stipulates that:
An lvalue is a variable that can get a memory address.
The non-Lvalue value is the right value.
As can be seen from here, can execute & Fetch address is the left value, the other is the right value.
It needs to be made clear that the ability to be assigned is not the difference between a C + + Lvalue and a right value.
We give four expressions:
string One ( " one " const string ( " two " string three () {return " three " ; const string Four () {return " four "; }
Here are four variable expressions, the following two are temporary variables, can not take the address, so belong to the right value, the front two is the left value.
Write a function here:
void Test (conststring &s) { "Test (const string &s): " << s << Endl;}
Then test:
Test (one), test (three ()), Test (four ());
Compile we found that this test can accept all variables.
We use another function to do the testing:
void Test (string &s) { "Test (String &s):" < < s << Endl;}
Then the test finds that only one can be called by.
We then provide two test functions, and then we compile and run the discovery:
Test (String &&&&s): Four
So we can come to the conclusion that
In C + +, const x& can accept all variables
X & can only accept normal variables
At the same time, we can see a feature of C + + overload resolution:
When a parameter can match multiple functions, it always matches the most accurate one.
For example, the above one, it can also accept the Const X&, but when the x& form of the parameter exists, immediately select the latter. Obviously the latter is specially prepared for it, and the semantics of the two are the most consistent. x& contains a modification semantics, which is consistent with one.
Introducing the const attribute
The above four expressions, we only discuss the left and right values, and we add the const for discussion.
So:
String one ("one"); belongs to the non-const lvalue const string, "one"; Const Lvalue String Three () {return "three";} Non-const right-value const string four () {return ' four ';} const right Value
The property of the Lvalue right value is orthogonal to Const.
Now introduce a problem, if sometimes need to distinguish four kinds of variables, then what method should be used?
In the previous discussion, we know that x& can be used to differentiate one, but the remaining three can be swallowed by the const x&, and obviously we need to provide some custom versions of parameters for some variables to prioritize different parameters for different variables.
C++11 provides an rvalue reference to differentiate the right value specifically, and we provide four functions:
voidTestConst string&1) {cout<<"Test (const string &s):"<< s <<Endl;}voidTeststring&s) {cout<<"Test (String &s):"<< s <<Endl;}voidTeststring&&s) {cout<<"Test (String &&s):"<< s <<Endl;}voidTestConst string&&s) {cout<<"Test (const string &&s):"<< s <<Endl;}
We use C++11 to compile and discover:
Test (String &&&&&&s): Four
We draw the best match:
X & Match Non-const left value
Const x& Matching const LVALUE
X && Match Non-const right value
Const X && Match Const right value
We can then use a function-by-feature test to discover:
x& only matches non-const lvalue, which is consistent with previous conclusions
Const x& can match all expressions
X && can only match non-const right value
Const X && can match const and non-const right values
OK, our problem is solved, when we need to distinguish the right value, we can use rvalue reference.
In fact, we generally do not need the const X &&, so we use the following three parameters:
void Test (string &s); Modify Semantics
void Test (string &&s); moving Semantics , later in this article
void Test (const string &s); constant Semantics
These three kinds of semantics are sufficient, we only use the modification and the constant semantics in the c++98, in the c++11, precisely in order to implement the moving semantics, we need to differentiate the right value, only then need to introduce the Rvalue reference .
The following is a c++11 rvalue reference for moving semantics.
c++11 rvalue Reference: Lvalue right-to-right value reference