Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa SFINAE Gagal untuk Fungsi Ahli Templat Kelas?

Mengapa SFINAE Gagal untuk Fungsi Ahli Templat Kelas?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-04 22:18:02743semak imbas

Why Does SFINAE Fail for Class Template Member Functions?

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:

  • Gunakan templat fungsi: Tentukan templat fungsi berasingan untuk setiap beban berlebihan, seperti yang ditunjukkan di bawah:
<code class="cpp">template <typename T>
void bar(Foo<T><- A) {}

template <typename T>
void bar(Foo<T><- B) {}
  • Gunakan pengkhususan templat kelas eksplisit: Tentukan templat kelas berasingan untuk setiap lebihan, seperti ditunjukkan di bawah:
<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!

Kenyataan:
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