Wat is SFINAE (Substitution Failure Is Not An Error) in C++?
sobes.tech AI
Antwoord van AI
SFINAE (Substitution Failure Is Not An Error) — dit is een regel in C++ die stelt dat als de compiler probeert de argumenten van een sjabloon te substitueren in de handtekening van een functie of klasse, en deze substitutie leidt tot incorrecte code (bijvoorbeeld het proberen te gebruiken van een lid dat niet bestaat voor dat type), dit niet onmiddellijk wordt beschouwd als een compilatiefout. In plaats daarvan negeert de compiler eenvoudigweg deze instantie van het sjabloon bij het oplossen van overloads of specialisaties.
Deze regel wordt gebruikt voor metaprogrammering op compileertijd, waardoor sjablonen kunnen worden gemaakt waarvan het gedrag afhangt van de eigenschappen van de sjabloonargumenten.
Voorbeelden van gebruik van SFINAE:
- Selectie tussen overloads of specialisaties van sjabloonklassen afhankelijk van de aanwezigheid van bepaalde leden of ondersteunde bewerkingen.
- Implementatie van concepten (voor C++20, toen expliciete concepten werden geïntroduceerd) om typen van sjablonen te beperken.
- Het maken van type traits.
Voorbeeld van gebruik van SFINAE met std::enable_if:
#include <iostream>
#include <type_traits> // Voor std::enable_if
// Sjabloonfunctie die alleen wordt gecompileerd voor gehele getal typen
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_if_integral(T value) {
std::cout << "Geheel getal type: " << value << std::endl;
}
// Sjabloonfunctie die alleen wordt gecompileerd voor drijvende-komma typen
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
print_if_floating_point(T value) {
std::cout << "Drijvende-komma type: " << value << std::endl;
}
int main() {
print_if_integral(5); // Roept de eerste functie aan
print_if_floating_point(3.14); // Roept de tweede functie aan
// print_if_integral("hallo"); // Compileerfout - substitutie mislukt, functies worden genegeerd
return 0;
}
In dit voorbeeld wordt std::enable_if gebruikt als returntype. Als de voorwaarde std::is_integral<T>::value waar is, levert std::enable_if het type void. Als de voorwaarde onwaar is, levert std::enable_if geen lid type, wat leidt tot een substitiefout in de functiesignatuur, en de compiler negeert deze specialisatie.