Memilih Fungsi Ahli Menggunakan Enable_If Conditions
Tugasnya ialah untuk menentukan pemanggilan fungsi ahli berdasarkan parameter templat kelas. Coretan kod berikut cuba mencapai perkara ini:
<code class="cpp">#include <iostream> #include <type_traits> template<typename T> struct Point { void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T &>::type* = 0) { std::cout << "T is int." << std::endl; } void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float &>::type* = 0) { std::cout << "T is not int." << std::endl; } };</code>
Walau bagaimanapun, kod ini gagal dihimpun dengan ralat "tiada jenis bernama 'type' dalam 'struct std::enable_if'".
SFINAE dalam Tindakan
Kunci untuk memahami isu ini terletak pada konsep Kegagalan Gantian Bukan Satu Ralat (SFINAE). Enable_if membenarkan kompilasi bersyarat berdasarkan hujah templat. Dalam kes ini, hujah templat T sudah diketahui apabila fungsi ahli dijadikan instantiated. Oleh itu, keadaan dinilai pada masa instantiasi dan fungsi yang sepadan dipilih.
Membetulkan Kod
Untuk membetulkannya, kita perlu memperkenalkan hujah templat tiruan yang adalah lalai kepada T. Ini membolehkan mekanisme SFINAE berfungsi seperti yang dimaksudkan. Kod yang diubah suai akan kelihatan seperti ini:
<code class="cpp">template<typename T> struct Point { template<typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { std::cout << "T is int." << std::endl; } template<typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { std::cout << "T is not int." << std::endl; } };</code>
Menghalang Pengkhususan Fungsi Ahli Eksplisit
Seperti yang ditunjukkan oleh HostileFork, kod asal membenarkan spesifikasi eksplisit argumen templat untuk fungsi ahli, yang boleh membawa kepada keputusan yang salah. Untuk mengelakkan ini, kami boleh menambah static_assert yang menyemak sama ada sebarang hujah templat disediakan. Ini memastikan bahawa fungsi ahli yang betul sentiasa digunakan berdasarkan hujah templat T. Kod yang diubah suai ialah:
<code class="cpp">template<typename T> struct Point { template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is int." << std::endl; } template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is not int." << std::endl; } };</code>
Atas ialah kandungan terperinci Bagaimana untuk Memilih Fungsi Ahli Berdasarkan Parameter Templat Menggunakan `enable_if`?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!