Using Trailing Requires Clauses
What are trailing requires clauses and when should I use them?
Trailing requires clauses are a way to specify constraints on function templates or member functions of class templates. They are placed after the function signature and before the function body.
Trailing requires clauses are particularly useful when you want to conditionally enable or disable member functions based on the template parameters of the class. Here's an example:
#include <concepts>
#include <iostream>
template <typename T>
class Container {
T value{T(3.14)};
public:
void printValue()
requires std::integral<T>
{
std::cout << "Integral value: " << value
<< '\n';
}
void printValue()
requires std::floating_point<T>
{
std::cout << "Floating-point value: "
<< value << '\n';
}
};
int main() {
Container<int> intContainer;
// Calls the integral version
intContainer.printValue();
Container<double> doubleContainer;
// Calls the floating-point version
doubleContainer.printValue();
}Integral value: 3
Floating-point value: 3.14In this example, the Container class template has two overloads of the printValue member function, each with a different trailing requires clause.
The first overload is enabled only when the template parameter T satisfies the std::integral concept, while the second overload is enabled only when T satisfies the std::floating_point concept.
This allows the appropriate version of printValue to be called based on the type used to instantiate the Container template.
Concepts in C++20
Learn how to use C++20 concepts to constrain template parameters, improve error messages, and enhance code readability.