Mis on SFINAE (Substitution Failure Is Not An Error) C++-s?
sobes.tech AI
Vastus AI-lt
SFINAE (Substitution Failure Is Not An Error) — see reegel C++ keeles, mis ütleb, et kui kompilaator püüab asendada mallargumente funktsiooni või klassi signatuuris, ning see asendus põhjustab ebaõige koodi (näiteks liikme kasutamine, mis selle tüübi jaoks ei eksisteeri), siis see ei loeta kohe kompileerimisveaks. Selle asemel lihtsalt ignoreerib kompilaator selle mallnäite signatuuris asendamise ebaõnnestumist.
See reegel on kasutusel meta-programmeerimisel kompileerimise etapis, võimaldades luua mallid, mille käitumine sõltub argumentide omadustest.
SFINAE kasutamise näited:
- Valik ülekoormatud funktsioonide või klassi mallide spetsialiseerimiste vahel, sõltuvalt teatud liikmete olemasolust või toetatud operatsioonidest.
- Kontseptsioonide (enne C++20, kus ilmusid selged kontseptsioonid) rakendamine tüübi piiranguteks.
- Tüübiväärtuste (type traits) loomine.
Näide SFINAE kasutamisest std::enable_if-ga:
#include <iostream>
#include <type_traits> // std::enable_if jaoks
// Mallfunktsioon, mis kompileerub ainult täisarvutüüpidel
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_if_integral(T value) {
std::cout << "Täisarvuline tüüp: " << value << std::endl;
}
// Mallfunktsioon, mis kompileerub ainult ujuvtüüpidel
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
print_if_floating_point(T value) {
std::cout << "Ujuvtüüp: " << value << std::endl;
}
int main() {
print_if_integral(5); // Kutsub esimese funktsiooni
print_if_floating_point(3.14); // Kutsub teise funktsiooni
// print_if_integral("tere"); // Viga — asendus ebaõnnestus, funktsioonid ignoreeritakse
return 0;
}
Selles näites kasutatakse std::enable_if tagastustüübina. Kui tingimus std::is_integral<T>::value on tõene, annab std::enable_if tüübi void. Kui tingimus on väär, ei anna std::enable_if type liiget, mis põhjustab asendusvea signatuuris ning kompilaator ignoreerib selle spetsialiseerimise.