[英]Why does std::forward have two overloads?
給定以下參考折疊規則
T& &
--> T&
T&& &
--> T&
T& &&
--> T&
T&& &&
--> T&&
第三和第四條規則暗示T(ref qualifer) &&
是恆等變換,即T&
停留在T&
並且T&&
停留在T&&
。 為什么我們有兩個std::forward
重載? 以下定義不能滿足所有目的嗎?
template <typename T, typename = std::enable_if_t<!std::is_const<T>::value>>
T&& forward(const typename std::remove_reference<T>::type& val) {
return static_cast<T&&>(const_cast<T&&>(val));
}
在這里, const std::remove_reference<T>&
服務的唯一目的是不進行復制。 enable_if
有助於確保僅在非 const 值上調用 function。 我不完全確定是否需要const_cast
,因為它不是 const 的引用本身。
由於forward
總是使用顯式模板參數調用,因此我們需要考慮兩種情況:
forward<Type&>(val)
這里的T
的類型在forward
將是T&
因此返回類型將是到T&
的恆等轉換forward<Type&&>(val)
這里的T
在forward
的類型將是T&&
因此返回類型將是到T&&
的身份轉換那么,為什么我們需要http://en.cppreference.com/w/cpp/utility/forward中描述的兩個重載?
注意:我不確定std::forward
是否曾經與const
類型一起使用,但在這種情況下我禁用forward
,因為我從未見過這樣使用它。 在這種情況下,移動語義也沒有真正意義。
一個良好的開端將是霍華德Hinnant(欣南特)的答案和論文上std::forward()
。
您的實現正確處理所有正常用例( T& --> T&
, T const& --> T const&
,以及T&& --> T&&
)。 它無法處理的是常見且容易出錯的錯誤,這些錯誤在您的實現中很難調試,但無法使用std::forward()
進行編譯。
鑒於這些定義:
struct Object { };
template <typename T, typename = std::enable_if_t<!std::is_const<T>::value>>
T&& my_forward(const typename std::remove_reference<T>::type& val) {
return static_cast<T&&>(const_cast<T&&>(val));
}
template <class T>
void foo(T&& ) { }
我可以將非const
引用傳遞給const
對象,這兩個都是左值的:
const Object o{};
foo(my_forward<Object&>(o)); // ok?? calls foo<Object&>
foo(std::forward<Object&>(o)); // error
和右值品種:
const Object o{};
foo(my_forward<Object>(o)); // ok?? calls foo<Object>
foo(std::forward<Object>(o)); // error
我可以將左值引用傳遞給rvalues:
foo(my_forward<Object&>(Object{})); // ok?? calls foo<Object&>
foo(std::forward<Object&>(Object{})); // error
前兩種情況導致可能修改意圖為const
對象(如果構造為const
,則可能是UB),最后一種情況是傳遞懸空左值引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.