Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Memilih Fungsi Ahli Berdasarkan Parameter Templat Menggunakan `enable_if`?

Bagaimana untuk Memilih Fungsi Ahli Berdasarkan Parameter Templat Menggunakan `enable_if`?

DDD
DDDasal
2024-10-25 19:06:39848semak imbas

How to Select a Member Function Based on a Template Parameter Using `enable_if`?

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!

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