Home / Forums / C++20 Concepts vs C++14/17 SFINAE (std::enable_if) for Template Constraints

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

C++20 Concepts vs C++14/17 SFINAE (std::enable_if) for Template Constraints

MatrixRecon
3D Math & Vectors
MEMBER
Rep: 225
Join Date: Jan 2025
Posts: 33
Thanks: 55
1y ago · Aug 22, 2024 3:40 PM
#1
Prior to C++20, constraining template arguments required complex SFINAE (Substitution Failure Is Not An Error) with
CODE
std::enable_if_t
and type traits.

C++20 introduced **Concepts** and **Requires Clauses**, providing readable compile-time constraints and clear compiler error messages.

1. The Legacy Way: C++14/17 SFINAE with
CODE
std::enable_if

CPP
#include <type_traits>
#include <iostream>

// Only allow floating point types (float, double)
template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
T CalculateLength(T x, T y) {
    return std::sqrt(x * x + y * y);
}


---

2. The Modern Way: C++20 Concepts
CPP
#include <concepts>
#include <cmath>

// Define a custom concept
template <typename T>
concept Numeric = std::is_integral_v<T> || std::is_floating_point_v<T>;

template <typename T>
concept VectorType = requires(T v) {
    { v.x } -> std::convertible_to<float>;
    { v.y } -> std::convertible_to<float>;
    { v.z } -> std::convertible_to<float>;
};

// Usage with requires clause
template <VectorType T>
float Magnitude(const T& vec) {
    return std::sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
}

// Or compact terse syntax
void PrintNumeric(Numeric auto value) {
    std::cout << "Value: " << value << "
";
}


Why Concepts Win:
1. Error messages are concise (e.g. *"constraints not satisfied: VectorType<int>"*) rather than 50 lines of template substitution error dump.
2. Faster compilation times.
3. Clean self-documenting APIs!
MatrixRecon · 3D Mathematics & View Matrix Calculations
The following users thanked MatrixRecon for this post:
KronoDev
C++ / Game Modder
MEMBER
Rep: 195
Join Date: Jan 2023
Posts: 32
Thanks: 48
1y ago · Aug 22, 2024 6:20 PM
#2
The difference in compiler error readability alone makes C++20 Concepts worth adopting immediately. No more scrolling through pages of nested template instantiation failures!
KronoDev - Keep coding, keep learning
DisasmGeek
Capstone & Keystone Specialist
MEMBER
Rep: 160
Join Date: Dec 2024
Posts: 21
Thanks: 38
1y ago · Aug 23, 2024 9:40 AM
#3
The
CPP
requires(T v) { ... }
expression syntax is so versatile for verifying method presence at compile time without manual
CODE
decltype
boilerplates.
DisasmGeek · Capstone / Keystone Engine Integration