cpp20 · advanced
C++20 Concepts & requires — Type Constraints Made Explicit
C++20 concepts let you attach named, checked constraints to template parameters. A concept is a compile-time boolean predicate defined with the 'requires' expression: you list expressions that must compile ({a+b}->same_as<T>) and nested boolean requirements (requires is_arithmetic_v<T>). When a call site provides a type that fails any requirement, the compiler immediately reports which constraint was violated — instead of the 50+ line instantiation error you'd get from unconstrained templates. Concepts also enable if constexpr branching and are used in overload resolution: the most-constrained satisfying overload wins. They replace most SFINAE / enable_if patterns with readable, self-documenting syntax.
A C++20 concept is a compile-time named predicate over a type: concept Name = requires(T a){ {expr}->Type; requires bool_const; }; the compiler checks it at the call site before instantiation, giving clear errors naming the violated constraint instead of template noise.
The code
// 1. Define a concepttemplate <typename T>concept Numeric = requires(T a, T b) { { a + b } -> std::same_as<T>; // valid expression + return type { a * b } -> std::same_as<T>; requires std::is_arithmetic_v<T>; // nested requirement};
// 2. Use it — constrained templatetemplate <Numeric T> // shorthand: requires Numeric<T>T add(T a, T b) { return a + b;}
// 3. Concept in if constexpr / requires clausetemplate <typename T>void process(T val) { if constexpr (Numeric<T>) // compile-time branch std::cout << val + val; else std::cout << "non-numeric";}
add(1, 2); // T=int → Numeric<int>=true ✓add(1.5, 2.5); // T=double → Numeric<double>=true ✓add("x", "y"); // T=const char* → false: no arithmetic ✗What this lesson walks through
- 01What is a C++20 concept?
- 02requires expression: checking valid expressions and return types
- 03Highlight: nested requirement is_arithmetic_v<T>
- 04int satisfies Numeric — constraint check
- 05const char* violates Numeric — immediate, readable error
- 06Constrained vs unconstrained — why concepts matter
- 07if constexpr + concepts: compile-time branching on type traits
A concept is a named, compile-time predicate over a type or value. It lets you express constraints on template parameters in readable, checked English-like syntax. Before C++20 you needed SFINAE or enable_if — with concepts the intent is explicit.
See it animated — step by step, at your own pace
Unlock the full interactive walkthrough of C++20 Concepts & requires — Type Constraints Made Explicit and 100+ animated C++ interview lessons.