1y ago · Aug 22, 2024 3:40 PM
Prior to C++20, constraining template arguments required complex SFINAE (Substitution Failure Is Not An Error) with 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
---
2. The Modern Way: C++20 Concepts
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!
CODE
std::enable_if_tC++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: