Mengapa SFINAE Gagal untuk Fungsi Ahli Templat Kelas?

Mary-Kate Olsen
Lepaskan: 2024-11-04 22:18:02
asal
794 orang telah melayarinya

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

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

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) {}
Salin selepas log masuk
  • 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>
Salin selepas log masuk

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!

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