Requirements describe the operations and properties a type or expression must provide. In generic C++, templates use these expectations to work across different types, much like compile-time duck typing. section 4.2.4
Checking whether something quacks
A plain template can call x.Quack(), but an unsuitable argument produces a potentially confusing compiler error. A named concept makes the requirement explicit: concept Quacks = requires(T t) { t.Quack(); }; A function constrained by requires Quacks<T> accepts only types satisfying that operation, producing a clearer diagnostic when the constraint is not met. section 4.2.4
Listing 4.6 Writing and using a concept
template<typename T>
concept Quacks = requires(T t) #1
{
t.Quack(); #2
};
template<typename T>
requires Quacks<T> #3
void must_be_a_duck(T x)
{
x.Quack();
}
Inspect the compact concept definition and its use on a function. section 4.2.4
Requirements also appear when library components depend on particular type behavior:
- std::chrono::time_point uses a Clock type that must meet the requirements for Clock; otherwise, apparently working operations may still be invalid. section 4.2.4
- A concept is a named set of requirements, allowing template interfaces to communicate their expectations directly. section 4.5
