C++ da SFINAE (Substitution Failure Is Not An Error) nima?
sobes.tech AI
AIdan javob
SFINAE (Substitution Failure Is Not An Error) — bu C++ dag'idagi qoidadir va agar kompilator shablon argumentlarini funksiya yoki sinf imzosiga almashtirishga harakat qilsa va bu almashtirish noto'g'ri kodga olib kelsa (masalan, bu tur uchun mavjud bo'lmagan a'zo elementini ishlatishga urinish), bu darhol kompilatsiya xatosi hisoblanmaydi. Buning o'rniga, kompilator shablonning bu nusxasini rad etadi va overload yoki maxsuslashtirishni hal qilishda e'tibor bermaydi.
Ushbu qoidalar kompilatsiya vaqtida metaprogrammalash uchun ishlatiladi, shablonlarning xatti-harakatlari shablon argumentlarining xususiyatlariga bog'liq bo'lishiga imkon beradi.
SFINAE qo'llanilishining misollari:
- Muayyan a'zolar yoki qo'llab-quvvatlanadigan operatsiyalar mavjudligiga qarab, overload qilingan funksiyalar yoki sinf shablonlarining maxsuslashtirishlari orasidan tanlash.
- (C++20 dan oldin, aniq konseptlar paydo bo'lishidan oldin) konseptlarni (concepts) amalga oshirish va shablon turlarini cheklash.
- Turlar xususiyatlarini (type traits) yaratish.
std::enable_if bilan SFINAE qo'llanilishining misoli:
#include <iostream>
#include <type_traits> // std::enable_if uchun
// Faqat butun son turlariga mos keladigan funksiya shabloni
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_if_integral(T value) {
std::cout << "Butun son turi: " << value << std::endl;
}
// Faqat suzuvchi nuqta turlariga mos keladigan funksiya shabloni
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
print_if_floating_point(T value) {
std::cout << "Suzuvchi nuqta turi: " << value << std::endl;
}
int main() {
print_if_integral(5); // Birinchi funksiyani chaqiradi
print_if_floating_point(3.14); // Ikkinchi funksiyani chaqiradi
// print_if_integral("salom"); // Kompilyatsiya xatosi - almashtirish muvaffaqiyatsiz, funksiyalar rad etiladi
return 0;
}
Ushbu misolda, std::enable_if qaytish turi sifatida ishlatiladi. Agar std::is_integral<T>::value haqiqat bo'lsa, std::enable_if void turini taqdim etadi. Agar noto'g'ri bo'lsa, std::enable_if type a'zosini taqdim etmaydi, bu esa funksiya imzasi bo'yicha almashtirish muvaffaqiyatsizligiga olib keladi va kompilator bu maxsuslashtirishni rad etadi.