Rumah > pembangunan bahagian belakang > C++ > Mengapakah std::forward menggunakan templat identiti untuk melumpuhkan potongan hujah templat?

Mengapakah std::forward menggunakan templat identiti untuk melumpuhkan potongan hujah templat?

Susan Sarandon
Lepaskan: 2024-11-09 09:34:02
asal
682 orang telah melayarinya

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

Melumpuhkan Potongan Argumen Templat dengan std::forward untuk Memastikan Pemajuan Betul

Pertimbangkan takrifan std::forward dalam VS2010:

<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>
Salin selepas log masuk

Tujuan templat identiti adalah untuk melumpuhkan potongan hujah templat. Mengapakah ini penting dalam senario ini?

Potongan hujah templat akan membawa kepada potongan jenis yang salah. Jika rujukan rnilai kepada objek jenis X dihantar kepada fungsi templat dengan jenis parameter T&, potongan hujah templat akan membuat kesimpulan T sebagai X, menghasilkan jenis parameter X&. Walau bagaimanapun, untuk pemajuan yang sempurna, parameter ialah nilai kerana ia mempunyai nama. Oleh itu, menggunakan potongan hujah templat dalam std::forward akan menyebabkan jenis parameter yang disimpulkan menjadi rujukan nilai atau rujukan nilai 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>
Salin selepas log masuk

Pertimbangkan contoh berikut:

<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>
Salin selepas log masuk

Dalam contoh ini, pemajuan sempurna gagal kerana parameter dalam perfect_forwarder dianggap sebagai rujukan lvalue atau const lvalue kerana namanya. Ini membawa kepada potongan jenis yang salah dalam forward_with_deduction, mengakibatkan semantik static_cast yang tidak diingini.

Melumpuhkan potongan hujah templat dengan templat identiti dalam std::forward memastikan std::forward sentiasa mengembalikan rujukan nilai, yang penting untuk pemajuan sempurna lnilai serta rnilai yang betul.

Atas ialah kandungan terperinci Mengapakah std::forward menggunakan templat identiti untuk melumpuhkan potongan hujah templat?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan