CodeNebula
C++11stlintermediate

std::enable_if (C++11 Addition)

C++11 · Modern Revolution · Compiler flag: -std=c++11

Explanation

A SFINAE utility that conditionally enables or disables template overloads based on a compile-time boolean condition, providing fine-grained control over overload resolution.

Real-World Scenario

Create a function overload that only accepts integral types, with a separate overload for floating-point types.

Quick Snippet

snippet.cpp
#include <type_traits>
template<typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
T double_value(T x) { return x * 2; }

Full Example

enable_if.cpp
// CodeNebula - C++11 Example: enable_if
// Compile: g++ -std=c++11 -Wall -Wextra -o example enable_if.cpp

// Demonstrates std::enable_if for SFINAE (Substitution Failure Is Not An Error).
// enable_if conditionally removes function overloads from consideration.

#include <iostream>
#include <type_traits>
#include <string>

// Only enabled for integral types
template<typename T>
typename std::enable_if<std::is_integral<T>::value, std::string>::type
classify(T val) {
    return std::to_string(val) + " is an integer";
}

// Only enabled for floating-point types
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, std::string>::type
classify(T val) {
    return std::to_string(val) + " is a float";
}

// enable_if as default template parameter
template<typename T,
         typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
T safe_add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << "=== std::enable_if ===" << std::endl;

    // SFINAE selects the correct overload
    std::cout << classify(42) << std::endl;
    std::cout << classify(3.14) << std::endl;
    std::cout << classify(true) << std::endl;
    std::cout << classify(2.5f) << std::endl;

    // safe_add only works with arithmetic types
    std::cout << "\nsafe_add(10, 20) = " << safe_add(10, 20) << std::endl;
    std::cout << "safe_add(1.5, 2.5) = " << safe_add(1.5, 2.5) << std::endl;

    // Uncommenting below would cause a compile error:
    // classify(std::string("hello"));  // no matching overload
    // safe_add(std::string("a"), std::string("b"));  // not arithmetic

    std::cout << "\nAll checks passed!" << std::endl;
    return 0;
}

// Expected output:
// === std::enable_if ===
// 42 is an integer
// 3.140000 is a float
// 1 is an integer
// 2.500000 is a float
//
// safe_add(10, 20) = 30
// safe_add(1.5, 2.5) = 4
//
// All checks passed!
Run command
g++ -std=c++11 -Wall -Wextra -o example enable_if.cpp