2011-09-08 62 views
0

我下一個片段從microsoft的std ::移動實現

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; 
} 

...

remote_integer x = frumple(5); 
remote_integer&& x1 = Move(x); 

,我得到一個錯誤「錯誤C2440: '迴歸':無法從 'remote_integer' 轉換到'remote_integer & &''

在編譯器中有所改變嗎?隨着std :: move一切順利。

+1

移動只接受一個右值,x是一個左值。你必須使用stdmove(小寫)。 – RedX

+0

http://social.msdn.microsoft.com/Forums/en-US/vs2010ctpcpp/thread/ab120b3c-4ecf-4a0d-8f64-f24925ac39a9/ - Jonathan Caves(Visual C++編譯器團隊)編寫實現std :: move和我的Move一樣。並移動我從微軟網站抓住,在問題的鏈接?那裏沒有問題,但是在VC10中它不起作用。 – Yola

+0

模板類型名稱RemoveReference ::類型&&移動(T && T){ 回報(RemoveReference ::類型&&)t; } - 現在一切工作正常,一些與類型轉換這裏 – Yola

回答

3

的原因,你的Move行不通,是因爲t總是左值(即使T&&解決,比方說,int&&)。即使它看起來很奇怪,命名右值引用確實是左值。

Move返回時,試圖將左值隱式綁定到右值引用,這是標準(第8.5.3節)所禁止的。正如評論中指出的那樣,你必須明確地將t轉換爲右值引用。

標準的相關部分中§5/ 4和§5/ 5,但我要引用筆記§5/ 6,其中總結這很好:

一般情況下,這樣的效果規則是名爲右值引用 被視爲左值,而對對象的未命名右值引用則被視爲xvalue;對函數的右值引用被視爲 左值是否被命名。

正確的執行確實是:

template <typename T> 
typename std::remove_reference<T>::type&& move(T&& t) 
{ 
    return static_cast<typename std::remove_reference<T>::type&&>(t); 
} 

據我記得,用這個代碼是在早期草稿有效。但是,由於規則發生了變化,現在必須提供明確的演員表(同樣適用於std :: forward)。