據我所知,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)
,如果兩者都具有相同的影響?
據我所知,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)
,如果兩者都具有相同的影響?
因爲完美轉發允許通過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創建臨時對象。
如果T&&
是一個rvalue引用,那麼T
是一個值,則static_cast<T>
使得拷貝不是右值參考。
該副本將綁定到右值引用(就像引用),但複製/移動ctors可能被不必要地調用,並且它不是elision的候選人。
static_cast<T&&>
將同時只投到一個右值引用。
它們在其他方面是相同的。
我同意雅克,但它比這更糟糕。
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>&&
。請注意,T
是std::vector<int>
,而不是std::vector<int> &&
。故事的道德:使用標準庫,它做的是正確的事,並且名稱forward
也比static_cast<something>
更好地捕捉了意圖。
您沒有嘗試'int&'。 – Quentin
@Quentin在這種情況下,它總是返回一個左值。 – Mikrosaft
'static_cast'會創建一個右值的副本 –