CodeBlanks Logo Icon CodeBlanks

enable_if

Learn SFINAE with enable_if.

enable_if (SFINAE)

std::enable_if produces a valid type when a condition is true and nothing when it is false. This relies on SFINAE (Substitution Failure Is Not An Error); a failed overload is silently dropped from the candidate set.

Example: template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>> T add_one(T x). This overload is a candidate only when T is an integer. add_one(5) works; add_one(std::string{...}) fails to compile. Before concepts this was the main tool to constrain templates.

Using enable_if_t

enable_if_t<cond> returns void (or a second parameter type) when the condition is true. It is commonly placed as a default template parameter: template <typename T, typename = std::enable_if_t<cond>>. This adds an invisible constraint to the signature.

Before C++17 you wrote typename std::enable_if<cond>::type. The _t suffix shortens it. In modern C++ concepts are a cleaner alternative, but enable_if is common in legacy code and worth knowing.

Practice Constrain add_one

Write template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>> T add_one(T x). The body should be return x + 1;. In main write std::cout << add_one(5);.

Starter code

main.cpp
#include <iostream>
#include <type_traits>

// Write add_one with enable_if

int main() {
    // Call add_one(5) and print
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <type_traits>

template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
T add_one(T x) {
    return x + 1;
}

int main() {
    std::cout << add_one(5);
    return 0;
}

Expected output

6

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does SFINAE stand for?

  • Single Function Is Not An Error
  • Static Function In A Namespace
  • Substitution Failure Is Not An Error Correct answer
  • Safe Function In Any Execution

Explanation: SFINAE stands for Substitution Failure Is Not An Error.

2 Match each expression to its role

Term Meaning
std::enable_if_t<cond> Type when condition is true
std::is_integral_v<T> The condition expression
typename = ... Empty default argument
add_one(5) A valid call

3 Complete the enable_if line

Question
template <typename T, typename = std::____<std::is_integral_v<T>>
T add_one(T x) { return x + 1; }
Answer
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>
T add_one(T x) { return x + 1; }

Explanation: enable_if_t<cond> yields a type when the condition is true.

All lessons in Advanced