標准庫move函數是使用右值引用的模板的一個很好的例子。標准庫是這樣定義std::move的:
template <typename T> typename remove_reference<T>::type&& move(T&& t) { return static_cast<typename remove_reference<T>::type&&>(t); }
我們考慮如下代碼的工作過程:
std::string s1("hi"), s2; s2 = std::move(string("hi")); // 正確,從一個右值移動數據 s2 = std::move(s1); // 正確,但是在賦值之后,s1的值是不確定的
在第一個賦值中,實參是string類型的右值,因此過程為:
- 推斷T的類型為 string
- remove_reference<string> 的 type 成員是 string
- move 返回類型是 string&&
- move 的函數參數t的類型為 string&&
因此,這個調用實例化 move<string>,即函數
string&& move(string &&t)
在第二個賦值中,實參是一個左值,因此:
- 推斷T的類型為 string&
- remove_reference<string&> 的 type 成員是 string
- move 返回類型是 string&&
- move 的函數參數t的類型為 string& &&,會折疊成 string&
因此,這個調用實例化 move<string&>,即
string&& move(string &t)
通常情況下,static_cast 只能用於其他合法的類型轉換。但是有一條針對右值的特許規則:雖然不能隱式的將一個左值轉換成右值引用,但我們可以用static_cast顯示的將一個左值轉換為一個右值。