CodeBlanks Logo Icon CodeBlanks

requires

Learn template constraints with the requires clause.

What is a requires clause?

The requires keyword appears in two forms: the requires clause (a template constraint) and the requires expression (an expression check). A requires expression checks whether a set of expressions is valid and returns bool.

Example: requires(T a, T b) { a + b; a - b; }. This expression returns true when both a + b and a - b are valid. It can live inside a concept or be used as a template constraint. This way the operations a type supports are queried at compile time.

Using a requires clause

To constrain a template function, write requires after the template header: template<typename T> requires Hashable<T> size_t hash_of(T v).

Now hash_of can be called only with types that satisfy Hashable. If the condition fails, the compiler gives a short and clear error. The requires clause can also combine concept names with && and ||: requires Hashable<T> && std::copyable<T>.

Practice Define the Hashable concept

Define the Hashable concept using the body requires(T a) { { std::hash<T>{}(a) } -> std::convertible_to<size_t>; }. In main test it with static_assert(Hashable<int>); and print "Hashable test passed" with std::cout.

Starter code

main.cpp
#include <iostream>
#include <concepts>
#include <functional>

// Define the Hashable concept here

int main() {
    // Test for int and print a message
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <concepts>
#include <functional>

template<typename T>
concept Hashable = requires(T a) {
    { std::hash<T>{}(a) } -> std::convertible_to<size_t>;
};

int main() {
    static_assert(Hashable<int>);
    std::cout << "Hashable test passed";
    return 0;
}

Expected output

Hashable test passed

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 the requires expression

Question
template<typename T> concept Hashable = ____(T a) { std::hash<T>{}(a); };
Answer
template<typename T> concept Hashable = requires(T a) { std::hash<T>{}(a); };

Explanation: A requires expression is written with a parameter list and a body.

2 What does requires(T a) { a.foo(); } check?

  • That a is a class
  • That a is not null
  • That the call a.foo() is valid on type a Correct answer
  • That a.foo() returns a method

Explanation: The requires expression checks whether the call a.foo() is valid at compile time.

3 Match each piece to its role

Term Meaning
requires(T a, T b) Expression check
requires Hashable<T> Template constraint
a + b Tested expression
std::hash<T>{}(a) Hash call

All lessons in Advanced