C ++ 11 value left and right reference value and the right value

[1] left value and the right value

In the C language, often left to bring value (lvalue), the right value (rvalue) this title.

And when compiling the program, the compiler sometimes contain values ​​left in the error message quoted in saying the right values.

But the value of the left and right values ​​are generally not through a rigorous definition known.

In fact, the reason why only know some judgment about the value of the left and right values ​​but rarely hear a reason for its real definition is difficult to generalize. And even summarized, still requires a lot of explanation.

A discriminating method (1) about the value of

Most of the time, one of the most typical method of discriminating about the value of:

In the assignment expression that appears in the left side of the equal sign is the "Left value", while on the right side of the equal sign, then known as the "right values." such as:

a = b + c;

In this assignment expression, a is a left value, and b + c is an rvalue.

Such identification value left, the right value of the method is still valid in C ++.

(2) The method of determining a value of about two

However, C ++, there is a widely accepted argument, that is:

Can take the address, has a name that is left of value, on the contrary, can not take the address, the name is not the right value.

Then the addition assignment expression, & a is allowed operations, but & (b + c) such an operation will not compile.

Thus a is a left value, (b + c) is an rvalue. These identification methods are usually very effective.

(3) The method of determining a value of about three

More detailed, 11 in C ++, the concept of the right two values ​​constituted by a pure rvalue (prvalue, Pure Rvalue), sucked death another value (xvalue, eXpiring Value).

Where the net value of the right is the concept of C ++ 98 standard, the right values, referring to the temporary variables used to identify and value that are not associated with the object.

For example: non-return type of the function return temporary variable reference value is a pure rvalue.

Some arithmetic expressions, such as 1 + 3 temporary variable values ​​generated is pure rvalue.

Rather than the literal value associated with the object, for example: 2, 'c', true, but also pure rvalue.

In addition, the return value of type conversion function, lambda expressions, etc., are also the right value.

And the death of the value of the C ++ 11 is the new value with the right references related expressions, such expression is usually the object is to be moved (shifted to other uses), such as:

[1] returns rvalue reference function returns the value T &&

[2] std :: move the return value

[3] Conversion Conversion function return value is of type T &&.

Remaining, the function may be identified, the value of the object belongs to a left value .

Therefore, in the program in C ++ 11, all values ​​will belong to the Left value will perish value, the value of one of the three pure and right.

[2] left and right reference value reference value

In C ++ 11, rvalue references (rvalue reference) is the right type of a reference value.

In order to distinguish it from prior reference types in C ++ 98, we call C ++ 98 referred to as "left reference value" (lvalue reference).

Rvalue references and lvalue references are of reference types, whether to declare a left or right reference value reference value, must be initialized immediately.

The reason for this can be understood as a reference to the type of itself does not own memory bound object, but an alias of the object.

Lvalue reference is an alias named variable value and the right value is quoted unnamed alias (anonymous) variable.

In fact, because the right values ​​generally do not have a name, we can only find its existence by reference.

Under normal circumstances, we can only get it right value expression references. such as:

T && a = ReturnRvalue();

The value of this expression, it is assumed ReturnRvalue the right to return a value, we declare one right, called a reference value, the function returns a value equal to ReturnRvalue temporary variables.

Right ReturnRvalue function returns a value at the end of an expression statement, its life will end up (usually we have an expression called lifetime).

The statement cited by the right values, the right-value and "rebirth", the lifetime value of a reference type variable life and the right of same.

That is, as long as a still "alive", which would have been the right value of the temporary amount "live" down. So, compared to a declarative statement of the following:

T b = ReturnRvalue();

Just rvalue reference variable declaration, a destructor will be less subject and a constructed object.

因为a是右值引用,直接绑定了ReturnRvalue()返回的临时量,而b只是由临时值构造而成的,而临时量在表达式结束后会被析构掉,因应就会多一次析构和构造的开销。

【3】常量左值引用 与 常量右值引用

(1)常量左值引用

通常情况下,右值引用是不能够绑定到任何的左值的。比如下面的表达式就是无法通过编译的:

int c;
int && d = c;

那么,在C++98标准中就已经出现的左值引用是否可以绑定到右值(由右值进行初始化)呢?比如:

T & e = ReturnRvalue();
const T & f = ReturnRvalue();

这样的语句是否能够通过编译呢?答案是:e的初始化会导致编译时错误,而f则不会。出现这样的状况的原因:

常量左值引用在C++98标准中开始就是个“万能”的引用类型。它可以接受非常量左值、常量左值、右值对其进行初始化。

而且,在使用右值对其初始化的时候,常量左值引用还可以像右值引用一样将右值的生命期延长。

不过相比于右值引用所引用的右值,常量左值所引用的右值在它的“余生”中只能是只读的。

相对地,非常量左值只能接受非常量左值对其进行初始化。

(2)常量右值引用

为了语义的完整,C++11中还存在着常量右值引用。比如通过以下代码声明一个常量右值引用:

const T && crvalueref = ReturnRvalue();

但是,一来右值引用主要就是为了移动语义,而移动语义需要右值是可以被修改的,那么常量右值引用在移动语义中就没有用武之处;

二来如果要引用右值且让右值不可以更改,常量左值引用往往就足够了。

因此,在现在的尴尬情况下,还没有看到常量右值引用有何用处。

(3)引用类型可引用值的类型表

下面列出了在C++11中各种引用类型可以引用的值的类型:

值得注意的是,只要能够绑定右值的引用类型,都能够延长右值的生命期。

【4】如何判断?

有的时候,我们可能不知道一个类型是否是引用类型,以及是左值引用还是右值引用(这在模板中比较常见)。

标准库在<type_traits>头文件中提供了3个模板类:is_rvalue_reference、is_lvalue_reference、is_reference,可供我们进行判断。比如:

 1 #include <iostream>
 2 #include <type_traits>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     cout << is_reference<int>::value << endl;              // 0
 8     cout << is_rvalue_reference<string &&>::value << endl; // 1
 9     cout << is_lvalue_reference<string &> ::value << endl; // 1
10     cout << is_rvalue_reference<const string &&>::value << endl; // 1
11     cout << is_lvalue_reference<const string &> ::value << endl; // 1
12 }

我们通过模板类的成员value就可以打印出stirng && 是否是一个右值引用了。

配合C++11中的类型推导操作符decltype,我们甚至还可以对变量的类型进行判断。

 

good good study, day day up.

顺序 选择 循环 总结

Guess you like

Origin www.cnblogs.com/Braveliu/p/12234824.html