Sobes.tech
Senior

C++-də SFINAE (Substitution Failure Is Not An Error) nədir?

sobes.tech Süni İntellekt

AI-dan cavab

SFINAE (Substitution Failure Is Not An Error) — bu C++-də bir qaydadır və əgər tərtibçi şablon arqumentlərini funksiya və ya sinifin imzasına yerinə qoymağa çalışırsa və bu yerinə qoyma düzgün olmayan kod gətirirsə (məsələn, bu tip üçün mövcud olmayan üzvü istifadə etməyə cəhd), bu dərhal tərtib xətası hesab edilmir. Əvəzində, tərtibçi sadəcə bu şablon nümunəsini nəzərə almadan overload və ya ixtisaslaşmanı həll edir.

Bu qayda tərtib vaxtı metaproqramlaşdırma üçün istifadə olunur və şablonların davranışını şablon arqumentlərinin xüsusiyyətlərinə bağlı edir.

SFINAE-nin istifadə nümunələri:

  • Müəyyən üzvlərin və ya dəstəklənən əməliyyatların mövcudluğuna əsasən overload edilmiş funksiyalar və ya sinif şablonlarının ixtisaslaşması arasında seçim.
  • (C++20-dən əvvəl, açıq konseptlərin ortaya çıxmasından əvvəl) konseptlərin (concepts) tətbiqi və şablon tiplərinin məhdudlaşdırılması.
  • Tip xüsusiyyətlərinin (type traits) yaradılması.

std::enable_if ilə SFINAE-nin istifadə nümunəsi:

#include <iostream>
#include <type_traits> // std::enable_if üçün

// Yalnız tam ədədi tiplər üçün tərtib olunan funksiya şablonu
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_if_integral(T value) {
    std::cout << "Tam ədəd tipi: " << value << std::endl;
}

// Yalnız ondalıklı tiplər üçün tərtib olunan funksiya şablonu
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
print_if_floating_point(T value) {
    std::cout << "Ondalıklı tip: " << value << std::endl;
}

int main() {
    print_if_integral(5);       // Birinci funksiyanı çağırır
    print_if_floating_point(3.14); // İkinci funksiyanı çağırır
    // print_if_integral("salam"); // Tərtib xətası - yerinə qoyma uğursuz, funksiyalar nəzərə alınmır

    return 0;
}

Bu nümunədə, std::enable_if geri dönüş tipi kimi istifadə olunur. Əgər std::is_integral<T>::value doğru olarsa, std::enable_if void tipini təmin edir. Əks halda, std::enable_if type üzvünü təmin etmir, bu da funksiya imzasında yerinə qoyma uğursuzluğuna səbəb olur və tərtibçi bu ixtisaslaşmanı nəzərə almır.