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&& forward(typename identity<_Ty>::type& _Arg) { // forward _Arg, given explicitly specified type parameter return ((_Ty&&)_Arg); }</code>
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&& forward_with_deduction(T&& obj) { return static_cast<T&&>(obj); }</code>
Pertimbangkan contoh berikut:
<code class="cpp">void test(int&){} void test(const int&){} void test(int&&){} template<typename T> void perfect_forwarder(T&& obj) { test(forward_with_deduction(obj)); } int main() { int x; const int& y(x); int&& z = std::move(x); test(forward_with_deduction(7)); // 7 is an int&&, correctly calls test(int&&) test(forward_with_deduction(z)); // z is treated as an int&, calls test(int&) // All the below call test(int&) or test(const int&) because in perfect_forwarder 'obj' is treated as // an int& or const int& (because it is named) so T in forward_with_deduction is deduced as int& // or const int&. The T&& in static_cast<T&&>(obj) then collapses to int& or const int& - 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>
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!