1. Problem It Solves
A requires expression asks whether a type supports specific syntax and properties before a template is selected. It makes an important assumption visible and checkable.
2. Prerequisites
Templates, expressions, and type traits from Day 3.
You should be able to compile a short program and read its output.
3. Core Idea
It is a compile-time checklist. Simple, type, compound, and nested requirements inspect increasingly precise parts of the proposed type contract. Read requires as a precise promise; runtime preconditions still belong to the programmer.
4. Minimal Syntax
requires(T a, T b) {
typename T::value_type;
{ a + b } -> std::same_as<T>;
}5. How It Works
The program introduces the smallest relevant form of
requires.It applies the feature to fixed data while required owners remain in scope.
It prints one result that can be checked against the source.
6. Common Mistakes
A requirement tests validity; it does not execute the expression and does not validate runtime values.
Also check the required header, C++20 library support, lifetime, and deduced types.
7. When to Use It
Use it when a template needs a structural contract that can be stated as valid types or expressions.
Avoid it when the condition depends on runtime data rather than the type interface.
8. Simple Example
A concept checks for a nested value_type, an addition expression, its result type, and a size condition. The companion .cpp uses no input, so its result is easy to reproduce.
Complete sample code
Source file
cpp20/07_requires_expressions_requirements/main.cpp
// Day 7: Requires Expressions and Requirement Kinds
#include <concepts>
#include <iostream>
struct Number {
using value_type = int;
int value{};
};
Number operator+(Number a, Number b) {
return {a.value + b.value};
}
template<class T>
concept SmallAddable = requires(T a, T b) {
typename T::value_type; // Type requirement
a + b; // Simple requirement
{ a + b } -> std::same_as<T>; // Compound requirement
requires (sizeof(T) <= 8); // Nested requirement
};
int main() {
std::cout << std::boolalpha << SmallAddable<Number> << '\n';
}
9. Key Takeaways
requiresexpresses the central C++20 idea of this day.The example isolates one behavior with fixed data.
Compiler checks do not replace lifetime and runtime reasoning.
Prefer the smallest interface that states the real requirement.
10. Self-Check Questions
Easy — What is the main job of
requiresin the minimal example?Medium — Which requirement fails first for a type that has no nested
value_typebut does supportoperator+?Hard — Why does
{ a + b } -> std::same_as<T>test more than the simple requirementa + b;?