拜讀Rvalue References: C++0x Features in VC10, Part 2的心得

具名的rvalue就是lvalue
這導致不管函式參數列怎麼寫
傳進來的參數
一律轉成lvalue

std::move的作用是
不管引數為何
一律轉成rvalue

std::forward的作用是
不管引數為何
保持r/lvalue屬性

術語

lvalue ref and rvalu ref

T&是lvalue ref

T&&是rvalue ref

參數與引數


void foo(int a, int b);

foo(5, 6);

“int a, int b"是參數
“5, 6″是引數

實作

std::move

可能的實作

template <typename T> struct RemoveReference {
 typedef T type;
};
template <typename T> struct RemoveReference<T&> {
 typedef T type;
};
template <typename T> struct RemoveReference<T&&> {
 typedef T type;
};
template <typename T> typename RemoveReference<T>::type&&
Move(T&& t) {
 return t;
}

 

RemoveReference顧名思義

就是移除掉&和&&
然後move return時再加上&&
因此
不管引數型別
最後全部都變成rvalue reference

std::forward

template <typename T> struct Identity {
 typedef T type;
};
template <typename T> T&& Forward(typename
Identity<T>::type&& t) {
 return t;
}

Identity並沒有轉換上的用途
只是避免模版參數推導而已
也就是讓forward(5)編譯失敗
強迫一定要寫成forward<int>(5)

forward本身則用到了特殊規則

引數 T T&&
int int& (特1) int& (特2)
int&& int int&&
特殊規則1:

當參數型別是 T&&

且引數是一個型別 A 的 lvalue 的時候

引數型別會推導為 A&

特殊規則2:

reference 會被折疊(reference collapse)

折疊的規則是:「lvalue reference 有傳染性」

X& &、X& && 還有 X&& & 都會變成 X&

只有 X&& && 會變成 X&&

所以 int& && 會被折疊成 int&。