Misalkan saya memiliki fungsi template dan dua kelas
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
Bagaimana cara melakukan pemeriksaan T adalah hewan? Saya tidak ingin memiliki sesuatu yang diperiksa selama waktu pengoperasian. Terima kasih
Jawaban:
Penggunaan
is_same
:#include <type_traits> template <typename T> void foo() { if (std::is_same<T, animal>::value) { /* ... */ } // optimizable... }
Biasanya, itu adalah desain yang sama sekali tidak bisa diterapkan, dan Anda benar-benar ingin mengkhususkan :
template <typename T> void foo() { /* generic implementation */ } template <> void foo<animal>() { /* specific for T = animal */ }
Perhatikan juga bahwa tidak biasa memiliki template fungsi dengan argumen eksplisit (tanpa deduksi). Ini tidak pernah terdengar, tetapi seringkali ada pendekatan yang lebih baik.
sumber
T
tidak disimpulkan, tidak banyak yang dapat Anda lakukan. Anda dapat membiarkan template utama tidak diterapkan dan membuat spesialisasi, atau Anda dapat menambahkan pernyataan statis denganis_same
.Saya pikir hari ini, lebih baik digunakan, tetapi hanya dengan C ++ 17.
#include <type_traits> template <typename T> void foo() { if constexpr (std::is_same_v<T, animal>) { // use type specific operations... } }
Jika Anda menggunakan beberapa jenis operasi khusus di if badan ekspresi tanpa
constexpr
, kode ini tidak akan dikompilasi.sumber
std::is_same<T, U>::value
Anda bisa menggunakan lebih pendek:std::is_same_v<T, U>
Di C ++ 17, kita bisa menggunakan varian .
Untuk menggunakan
std::variant
, Anda perlu menyertakan tajuk:#include <variant>
Setelah itu, Anda dapat menambahkan
std::variant
kode Anda seperti ini:using Type = std::variant<Animal, Person>; template <class T> void foo(Type type) { if (std::is_same_v<type, Animal>) { // Do stuff... } else { // Do stuff... } }
sumber
type
yang merupakan nilai tipeType
atau templat yang tidak masuk akal di sini)is_same_v
tidak bermakna dalam konteksvariant
. "Sifat" yang sesuai adalahholds_alternative
.std::variant
sama sekali tidak diperlukan di siniAnda dapat mengkhususkan template Anda berdasarkan apa yang diteruskan ke parameternya seperti ini:
template <> void foo<animal> { }
Perhatikan bahwa ini membuat fungsi yang sepenuhnya baru berdasarkan jenis yang diteruskan sebagai
T
. Ini biasanya lebih disukai karena mengurangi kekacauan dan pada dasarnya merupakan alasan kami memiliki template di tempat pertama.sumber