C++ requires Keyword

The requires keyword in C++20 is used to define constraints for templates and concepts. It provides a way to specify conditions that must be satisfied for a template or function to be instantiated. This makes templates more expressive and easier to debug by explicitly stating the requirements for their usage.

The requires keyword can be used in two main ways:

  1. As a part of a requires clause to constrain templates.
  2. In a requires expression to evaluate conditions within a concept.

Syntax

Requires Clause: A requires clause specifies conditions that must be satisfied for the template to be instantiated.

</>
Copy
template
requires condition
return_type function_name(T parameter);

Requires Expression: A requires expression defines a set of requirements for a type or a set of operations.

</>
Copy
requires (condition1 && condition2) {
    // Requirements
}

Examples

Example 1: Using requires Clause

This example uses a requires clause to constrain a template function that requires the type T to support addition.

</>
Copy
#include <iostream>
#include <concepts>
using namespace std;

template<typename T>
requires requires (T a, T b) { a + b; }
T add(T a, T b) {
    return a + b;
}

int main() {
    cout << "Sum of 3 and 5: " << add(3, 5) << endl;
    // Uncommenting the following line will cause a compilation error
    // because strings do not support direct addition.
    // cout << "Sum of strings: " << add(string("Hello"), string("World")) << endl;
    return 0;
}

Output:

Sum of 3 and 5: 8

Explanation:

  1. The requires clause ensures that the type T supports the + operator.
  2. If a type does not satisfy this condition, a compile-time error occurs, improving error diagnostics.
  3. The function add works correctly for integers, as they support addition.

Example 2: Using requires Expression

This example demonstrates a requires expression inside a concept to define constraints for a type.

</>
Copy
#include <iostream>
#include <concepts>
using namespace std;

template<typename T>
concept Multipliable = requires (T a, T b) {
    { a * b } -> convertible_to<T>;
};

template<Multipliable T>
T multiply(T a, T b) {
    return a * b;
}

int main() {
    cout << "Product of 4 and 5: " << multiply(4, 5) << endl;
    return 0;
}

Output:

Product of 4 and 5: 20

Explanation:

  1. The Multipliable concept uses a requires expression to ensure that the type supports multiplication.
  2. The template function multiply is constrained to types that satisfy the Multipliable concept.
  3. The program works for integers as they support multiplication, and the result is printed.

Key Points to Remember about requires Keyword

  1. The requires keyword is used to define constraints for templates and concepts in C++20.
  2. It can be used in a requires clause or as a requires expression.
  3. Constraints defined with requires help ensure that templates are only instantiated with valid types.
  4. Using requires improves code clarity, maintainability, and error diagnostics.
  5. The requires keyword is a powerful tool for modern C++ template programming.