SFINAE Gagal untuk Fungsi Ahli Templat Kelas
Mekanisme Kegagalan Pengganti, Bukan Ralat (SFINAE), biasanya digunakan dalam pengaturcaraan meta templat, nampaknya mempamerkan tingkah laku yang pelik apabila digunakan pada fungsi ahli templat kelas.
The Masalah
Pertimbangkan coretan kod berikut:
<code class="cpp">#include <type_traits> struct A{}; struct B{}; template <typename T> struct Foo { // Conditional enable bar() for T == A typename std::enable_if<std::is_same<T, A>::value>::type bar() {} // Conditional enable bar() for T == B typename std::enable_if<std::is_same<T, B>::value>::type bar() {} };</code>
Kod ini cuba mentakrifkan dua lebihan bar() dalam templat kelas Foo, dengan SFINAE digunakan untuk mendayakan setiap lebihan beban secara bersyarat berdasarkan nilai T. Walau bagaimanapun, kod tersebut gagal untuk disusun dengan yang berikut ralat:
<code class="cpp">error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded</code>
Penjelasan
SFINAE biasanya digunakan untuk mendayakan atau melumpuhkan pengkhususan templat berdasarkan hujah templat. Walau bagaimanapun, SFINAE hanya terpakai pada deduced hujah templat, bermaksud hujah yang disimpulkan secara automatik semasa resolusi lebihan. Dalam kes fungsi ahli, hujah templat tidak disimpulkan tetapi dinyatakan secara eksplisit apabila membuat contoh kelas. Oleh itu, SFINAE tidak boleh digunakan untuk fungsi ahli.
Penyelesaian
Terdapat dua cara utama untuk menangani isu ini:
<code class="cpp">template <typename T> void bar(Foo<T><- A) {} template <typename T> void bar(Foo<T><- B) {}
<code class="cpp">template <typename> struct Foo; template <> struct Foo<A> { void bar() {} }; template <> struct Foo<B> { void bar() {} };</code>
Atas ialah kandungan terperinci Mengapa SFINAE Gagal untuk Fungsi Ahli Templat Kelas?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!