首頁 >後端開發 >C++ >為什麼 std::forward 使用恆等模板來停用模板參數推導?

為什麼 std::forward 使用恆等模板來停用模板參數推導?

Susan Sarandon
Susan Sarandon原創
2024-11-09 09:34:02683瀏覽

Why does std::forward use the identity template to disable template argument deduction?

停用std::forward 的範本參數推導以確保正確轉送

考慮VS2010 中std::forward 的定義:

<code class="cpp">template<class _Ty> inline
_Ty&amp;&amp; forward(typename identity<_Ty>::type&amp; _Arg)
{   // forward _Arg, given explicitly specified type parameter
    return ((_Ty&amp;&amp;)_Arg);
}</code>

身分範本的目的是停用範本參數推導。為什麼這在這種情況下至關重要?

模板參數推導會導致錯誤的類型推導。如果類型 X 的物件的右值參考傳遞給參數類型為 T& 的模板函數,則模板實參推導會將 T 推斷為 X,從而產生參數類型 X&。然而,對於完美轉發,參數是左值,因為它有名稱。因此,在 std::forward 中使用模板參數推導將導致推導的參數類型成為左值參考或 const 左值參考。
<code class="cpp">template<typename T>
T&amp;&amp; forward_with_deduction(T&amp;&amp; obj)
{
    return static_cast<T&amp;&amp;>(obj);
}</code>

考慮以下範例:
<code class="cpp">void test(int&amp;){}
void test(const int&amp;){}
void test(int&amp;&amp;){}

template<typename T>
void perfect_forwarder(T&amp;&amp; obj)
{
    test(forward_with_deduction(obj));
}

int main()
{
    int x;
    const int&amp; y(x);
    int&amp;&amp; z = std::move(x);

    test(forward_with_deduction(7));    //  7 is an int&amp;&amp;, correctly calls test(int&amp;&amp;)
    test(forward_with_deduction(z));    //  z is treated as an int&amp;, calls test(int&amp;)

    //  All the below call test(int&amp;) or test(const int&amp;) because in perfect_forwarder 'obj' is treated as
    //  an int&amp; or const int&amp; (because it is named) so T in forward_with_deduction is deduced as int&amp; 
    //  or const int&amp;. The T&amp;&amp; in static_cast<T&amp;&amp;>(obj) then collapses to int&amp; or const int&amp; - 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));
}</code>

在此範例中,完美轉送失敗,因為Perfect_forwarder 中的參數因其名稱而被視為左值或const 左值引用。這會導致forward_with_deduction中的類型推導不正確,產生不必要的static_cast語意。

在std::forward中停用具有身分範本的範本參數推導可確保std::forward始終傳回右值引用,這對於正確完美轉送左值和右值。

以上是為什麼 std::forward 使用恆等模板來停用模板參數推導?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn