2015-09-27 44 views
6

據我所知,std::forward<T>(x)相當於static_cast<T&&>(x)C++ std :: forward <T> vs static_cast <T>

但是從我所看到的,static_cast<T>(x)似乎做同樣的事情,因爲可以在下面的code

我的問題可以看出因此也是爲什麼std::forward<T>作爲static_cast<T&&>(x)實現的,而不是static_cast<T>(x),如果兩者都具有相同的影響?

+1

您沒有嘗試'int&'。 – Quentin

+0

@Quentin在這種情況下,它總是返回一個左值。 – Mikrosaft

+0

'static_cast '會創建一個右值的副本 –

回答

10

因爲完美轉發允許通過r值參考l值參考。這是通過reference collapsing完成:

T = int --> T&& = int&& 
T = int& --> T&& = int& && = int& 
T = int&& --> T&& = int&& && = int&& 

在你的榜樣與static_cast<T>你只是失去r值引用。它適用於原始類型(因爲傳遞int通常會複製一個CPU寄存器值),但對於複雜類型會很糟糕,因爲它會導致通過複製ctors創建臨時對象。

+0

我剛檢查過它,它實際上調用了rvalue的拷貝構造函數。 但是爲什麼?我讀到,如果我們用rvalue調用func(),則T被推斷爲int &&,因此static_cast (x)將變爲static_cast (x)。 那麼爲什麼它會創建一個副本? – Mikrosaft

+2

'static_cast '可以返回一個參考:上面的答案意味着它不能。你能否澄清這個問題只發生在一個「案例」中? – Yakk

+0

@Mikrosaft:不,「T」不能推導爲「int &&」,它只能是「int」或「int&'。 – myaut

2

如果T&&是一個rvalue引用,那麼T是一個值,則static_cast<T>使得拷貝不是右值參考。

該副本將綁定到右值引用(就像引用),但複製/移動ctors可能被不必要地調用,並且它不是elision的候選人。

static_cast<T&&>將同時只投到一個右值引用。

它們在其他方面是相同的。

0

我同意雅克,但它比這更糟糕。

void foo(const std::vector<int> &vec); 

template<typename T> 
void callFoo(T &&data) 
{ 
    foo(static_cast<T>(data)); 
} 

int main() 
{ 
    callFoo(std::vector<int>{/*...*/}); 
} 

這將始終創建副本。載體是而不是,因爲data作爲表達式是std::vector<int>類型的左值,即使取代類型爲std::vector<int>&&。請注意,Tstd::vector<int>,而不是std::vector<int> &&。故事的道德:使用標準庫,它做的是正確的事,並且名稱forward也比static_cast<something>更好地捕捉了意圖。

相關問題