簡體   English   中英

為什么 std::forward 有兩個重載?

[英]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總是使用顯式模板參數調用,因此我們需要考慮兩種情況:

  1. forward<Type&>(val)這里的T的類型在forward將是T&因此返回類型將是到T&的恆等轉換
  2. forward<Type&&>(val)這里的Tforward的類型將是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM