Ce face std::enable_if
std::enable_if_t<conditie, T> este tipul T dacă condiția este adevărată și nu există deloc dacă este falsă. Pus în semnătura unui șablon, face ca funcția să „dispară” pentru tipurile care nu îndeplinesc condiția, iar compilatorul alege altă variantă sau dă eroare. Regula din spate se numește SFINAE („eșecul substituției nu este o eroare”).
Este tehnica clasică din C++11/14/17. În C++20 conceptele și requires fac același lucru mult mai clar (vezi std::integral), dar enable_if apare foarte des în cod existent.
Parametri
| Parametru | Descriere |
|---|---|
Conditie |
Expresie bool evaluată la compilare. |
T |
Tipul rezultat când condiția este adevărată (implicit void). |
Ce returnează
Tipul T, dacă Conditie este adevărată.
Exemple
Exemplul 1: Două variante ale aceleiași funcții
Pentru fiecare apel, doar una dintre cele două funcții există, în funcție de tipul argumentului.
#include <print>
#include <type_traits>
template <class T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
void afiseaza(T x) {
std::println("întreg: {}", x);
}
template <class T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
void afiseaza(T x) {
std::println("real: {:.3f}", x);
}
int main() {
afiseaza(42);
afiseaza(3.14159);
// afiseaza("text"); // nu compilează: nicio variantă nu se potrivește
}
Rezultat
întreg: 42
real: 3.142
Exemplul 2: Același lucru cu un concept (C++20)
#include <concepts>
#include <print>
void afiseaza(std::integral auto x) { std::println("întreg: {}", x); }
void afiseaza(std::floating_point auto x) { std::println("real: {:.3f}", x); }
int main() {
afiseaza(42);
afiseaza(3.14159);
}
Rezultat
întreg: 42
real: 3.142
Greșeli frecvente
- Pui
enable_ifîn două funcții care diferă doar prin argumentul implicit (class = std::enable_if_t<...>). Compilatorul le vede ca redeclarări ale aceleiași funcții; folosește formastd::enable_if_t<..., int> = 0.
Comenzi înrudite
std::integral: Concepte C++20 care restrâng un șablon la tipuri întregi (integral) sau reale (floating_point).std::is_integral: is_integral verifică dacă un tip este întreg (inclusiv bool și char); is_floating_point, dacă este real.requires: Scrie cerințe pentru parametrii unui șablon: ca clauză care restrânge șablonul sau ca expresie care verifică dacă un cod este valid.concept: Dă un nume unui set de cerințe pentru tipuri, folosit ca să restrângi ce tipuri acceptă un șablon.template: Scrie o funcție sau o clasă o singură dată, pentru orice tip; compilatorul generează varianta potrivită pentru fiecare tip folosit.