C++ `std::enable_if` | Conditional Templates and SFINAE
이 글의 핵심
`std::enable_if` removes overload candidates when a condition is false—core SFINAE machinery before concepts.
What is enable_if?
Conditionally enable template declarations when a predicate is true.
#include <type_traits>
template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
func(T value) {
return value * 2;
}
func(10); // OK: int
// func(3.14); // error: double
Basic syntax
// enable_if<condition, type>::type
std::enable_if<true, int>::type // int
std::enable_if<false, int>::type // no ::type (SFINAE)
// C++14 alias
std::enable_if_t<condition, type>
Examples
Return type
template<typename T>
std::enable_if_t<std::is_integral<T>::value, T>
multiply(T a, T b) {
return a * b;
}
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, T>
multiply(T a, T b) {
return a * b * 1.1;
}
Default template parameter
template<typename T,
typename = std::enable_if_t<std::is_arithmetic<T>::value>>
class Calculator {
T value;
public:
Calculator(T v) : value(v) {}
T add(T x) { return value + x; }
};
Dummy function parameter
template<typename T>
void print(T value,
std::enable_if_t<std::is_pointer<T>::value>* = nullptr) {
std::cout << "pointer: " << *value << std::endl;
}
template<typename T>
void print(T value,
std::enable_if_t<!std::is_pointer<T>::value>* = nullptr) {
std::cout << "value: " << value << std::endl;
}
Multiple conditions
template<typename T>
std::enable_if_t<
std::is_integral<T>::value &&
!std::is_same<T, bool>::value,
T>
increment(T value) {
return value + 1;
}
C++20 concepts alternative
template<typename T>
concept Integral = std::is_integral_v<T>;
template<Integral T>
T multiply(T a, T b) {
return a * b;
}
Common pitfalls
- Readability—prefer
enable_if_tand concepts. - Overlapping predicates—make conditions mutually exclusive.
- Error messages—add
static_assertin a single overload if clearer.
Practical patterns
Pointers only, copy-constructible checks, sizeof bounds—same ideas as the Korean article.
FAQ
SFINAE: Substitution Failure Is Not An Error—failed substitution removes a candidate, it is not always an error.
Related posts
- SFINAE
- Type traits
- SFINAE & Concepts
Keywords
C++, enable_if, SFINAE, templates, metaprogramming.
See also
- SFINAE
- SFINAE deep dive series
- Tag dispatch
- Type traits