簡體   English   中英

std::forward() 的右值引用重載的目的是什么?

[英]What is the purpose of std::forward()'s rvalue reference overload?

我正在試驗完美轉發,我發現std::forward()需要兩個重載:

超載編號 1:

template <typename T>
inline T&& forward(typename 
std::remove_reference<T>::type& t) noexcept
{
    return static_cast<T&&>(t);
}

重載 nr.2:

template <typename T>
inline T&& forward(typename 
std::remove_reference<T>::type&& t) noexcept
{
    static_assert(!std::is_lvalue_reference<T>::value,
              "Can not forward an rvalue as an lvalue.");
    return static_cast<T&&>(t);
}

現在完美轉發的典型場景是這樣的

template <typename T>
void wrapper(T&& e)
{
    wrapped(forward<T>(e));
}

當然你知道當wrapper()被實例化時, T取決於傳遞給它的參數是左值還是右值。 如果它是U類型的左值,則T被推導為U& 如果是右值,則將T推導為U

在任何情況下 - 在wrapper()的范圍內 - e是一個左值,因此它總是使用std::forward()的第一個重載。

現在我的問題:

使用(並且需要)第二次重載的有效場景是什么?

N2951中詳細討論了forward的設計原理。

本文檔列出了 6 個用例:

A.應該將左值作為左值轉發。 所有實現都通過了這個測試。 但這不是經典的完美轉發模式。 此測試的目的是表明實現 2 未能實現其防止除完美轉發之外的所有用例的既定目標。

B.應該將右值作為右值轉發。 與用例 A 一樣,這是一個身份轉換,這提供了一個需要身份轉換的激勵示例。

C.應該轉發右值作為左值。 此用例展示了意外創建懸空引用的危險情況。

D.應該將較少的 cv 限定表達式轉發到更多 cv 限定的表達式。 一個激勵用例,涉及在轉發期間添加 const。

E.應該將派生類型的表達式轉發到可訪問的、明確的基類型。 一個激勵用例,涉及將派生類型轉發到基類型。

F.應該轉發任意類型轉換。 此用例演示了前向中的任意轉換如何導致懸空引用運行時錯誤。

第二個重載啟用情況 B 和 C。

該論文繼續提供每個用例的示例,這些示例太長,無法在此重復。

更新

我剛剛通過這 6 個用例運行了第一個重載的“解決方案”,這個練習表明第二個重載也啟用了用例 F:不應轉發任意類型轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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