2012年12月25日 星期二

[C++] Lvalue reference and Rvalue reference

Rvalue reference是從C++11正式被引入的一個屬性
而由於它的引入, 讓move semantics被介紹出來

move constructor與copy constructor不同處在於
較少的memory allocation/de-allocation 和copy, 因此效能也會比較好
Move Constructor不在此文中介紹, 就留待下篇文章吧!

以下節錄自(http://binglongx.wordpress.com/2010/08/20/c0x-rvalue-reference/)
===============================================================
In C++0x (see N2844N2812), the rules are (with const correctness in mind):
  • lvalue reference T& binds to modifiable lvalues only; (making no sense to modify a temporary) (!VC10 is different)
  • lvalue reference T const& (i.e., const T&) binds to all modifiable/const lvalues and rvalues; (harmless const reference)
  • rvalue reference T&& binds to modifiable rvalues only; (do not steal resource from a non-temporary )
  • rvalue reference T const&& (i.e., const T&&) binds to modifiable and const rvalues;
Because a reference itself is an expression, there are rules regarding whether it’s lvalue or rvalue:
  • Named lvalue reference is lvalue;         T& tr = t; // tr is lvalue.
  • Unnamed lvalue reference is lvalue;      std::vector tv; tv.at(); // tv.at() is lvalue, backing object is non-temporary.
  • Named rvalue reference is lvalue;         void foo(T&& t){ // t is lvalue, t’s type is rvalue reference.
  • Unnamed rvalue reference is rvalue;
Named rvalue reference is lvalue. This is convoluted and confusing, isn’t it? In the function body of void foo(T&& t), t is bound to an afloat rvalue object in the caller’s site, from which you can steal its guts, but t itself is lvalue. That means, if you try to pass t in this function to another function, the other function would perceive t as lvalue, and therefore t loses its rvalue-ness. Why? The reason that a named rvalue reference is a lvalue, is because with a name it can be referred to by many occurrences, and obviously not all of these occurrences can steal its resource. If this is not enforced, in the function body of void foo(T&& t), if t is passed to two other functions that expect rvalue, which of them should take t’s guts? No matter which, the program is ill-fated. C++0x makes sure the program is safe by giving the two functions only lvalue so they cannot steal from t. Once you understand this, it is no longer confusing.
================================================================
lvalue reference: 可以想像成是一個物件的另一個名字, 也就是傳統c++所指的reference; reference必須是已經被初始化且不可被改變的. 宣告方法就是type&
例如:
int a = 1;
int &b = a; // it is a lvalue reference, reference to a object

rvalue reference: 與lvalue reference很像, 但是不同的地方是rvalue reference can bind to a temporary (rvalue), 但是 (non-const)lvalue reference can't bind to a rvalue. 宣告方法為 type&&
這個可以回顧一下之前的Lvalue 與 Rvalue的定義說明以及lvalue reference的說明(reference必須是已經被初始化且不可以被改變的)
例如:
A a;
A&& a_ref = a; // an rvalue reference
A& a_ref2 = A(); // Error
A&& a_ref3 = A(); // OK

Reference

沒有留言:

張貼留言