使用std::forward 停用範本參數推導以確保正確轉送
考慮VS2010 中std::forward 的定義:
template inline
_Ty&& forward(typename identity<_Ty>::type& _Arg)
{ // forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}
身分範本的目的是停用範本參數推導。為什麼這在這種情況下至關重要?
模板參數推導會導致錯誤的型別推導。如果對類型 X 的物件的右值參考傳遞給參數類型為 T& 的模板函數,則模板實參推導會將 T 推斷為 X,從而產生參數類型 X&。然而,對於完美轉發,參數是左值,因為它有名稱。因此,在 std::forward 中使用模板參數推導將導致推導的參數類型為左值參考或 const 左值參考。
template
T&& forward_with_deduction(T&& obj)
{
return static_cast考慮以下範例:
void test(int&){}
void test(const int&){}
void test(int&&){}
template
void perfect_forwarder(T&& obj)
{
test(forward_with_deduction(obj));
}
int main()
{
int x;
const int& y(x);
int&& z = std::move(x);
test(forward_with_deduction(7)); // 7 is an int&&, correctly calls test(int&&)
test(forward_with_deduction(z)); // z is treated as an int&, calls test(int&)
// All the below call test(int&) or test(const int&) because in perfect_forwarder 'obj' is treated as
// an int& or const int& (because it is named) so T in forward_with_deduction is deduced as int&
// or const int&. The T&& in static_cast<T&&>(obj) then collapses to int& or const int& - which is not what
// we want in the bottom two cases.
perfect_forwarder(x);
perfect_forwarder(y);
perfect_forwarder(std::move(x));
perfect_forwarder(std::move(y));
}
在此範例中,完美轉送失敗,因為 Perfect_forwarder 中的參數因其名稱而被視為左值或 const 左值參考。這會導致forward_with_deduction中的類型推導不正確,產生不必要的static_cast語意。
在std::forward中停用具有識別範本的範本參數推導可確保std::forward始終傳回右值引用,這對於正確完美轉送左值和右值。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3