A concept (C++20) is a named set of constraints on a template parameter in C++. It is the Template Metaprogramming equivalent of a Rust trait bound.
Example
template <typename T>
concept Numeric = std::is_arithmetic_v<T>;
template <Numeric T>
T add(T a, T b) { return a + b; }
add(1, 2); // ok
add("a", "b"); // compile error: const char* does not satisfy NumericDefining Concepts
Concepts can compose type traits, expressions, and other concepts:
template <typename T>
concept Printable = requires(T t) {
{ std::cout << t } -> std::same_as<std::ostream&>;
};
template <typename T>
concept Summable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};The requires expression lists what the type must support. If any expression inside is ill-formed, the concept evaluates to false.
Syntax Variants
// Shorthand: concept as type constraint
template <Numeric T>
T square(T x) { return x * x; }
// Requires clause
template <typename T>
requires Numeric<T>
T square(T x) { return x * x; }
// Trailing requires
template <typename T>
T square(T x) requires Numeric<T> { return x * x; }
// Abbreviated function template (auto)
auto square(Numeric auto x) { return x * x; }Concepts are the closest C++ gets to Rust traits, but they only constrain; Rust traits also provide default implementations.