먼저 예시 코드를 살펴보자.

#include <iostream>
#include <type_traits>
 
template<typename T>
std::enable_if_t<std::is_integral<T>::value, void>
print(T val) {
    std::cout << "Integral: " << val << "\n";
}
 
template<typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
print(T val) {
    std::cout << "Floating point: " << val << "\n";
}
 
int main() {
    print(10);     // Integral version
    print(3.14);   // Floating point version
    // print("hi");  // ❌ Compile error — no matching overload
}

타입에 따른 처리를 한다는 점에서 Templete Specialize와 비슷한 동작을 한다고 볼 수 있지만 조금 다른 부분이 있다.

타입을 보다 엄격하게 컴파일 타임에 체크한다는 점이다.

이는 런타임에 발생할 수 있는 에러에 대해서 보다 엄격하게 확인할 수 있다는 점에서 이점을 가진다.

이름은 에러가 아니라는데 왜 에러를 발생 시키냐고 생각되는데 아마 런타임에 에러를 발생시키지 않고 컴파일 타임에 발생시킨다는 의미가 아닐까 싶다.