I'm trying to wrap my head around concepts
in C++20. Consider the following (very simple) concept:
template <typename T>
concept Float = requires
{
std::floating_point<T>;
};
I can write a templated class using this concept in 2 ways:
template <Float T>
class MyClass {
public:
MyClass(T val) : value{ val } {};
private:
T value;
};
Or I can do
template <typename T> requires Float<T>
class MyClass {
public:
MyClass(T val) : value{ val } {};
private:
T value;
};
In this particular example, these behave exactly the same. Is this always the case though? Are there situations where it is easier to express some constraint using the template <...> requires ...
syntax? Or is this merely a style preference/convention?
The only thing I can think of right now is that using the template <...> requires ...
syntax may allow you represent relational constraints between multiple template arguments, where as the template <CONCEPT T>
syntax only allows you to represent a constraint on a single argument?
Any guidance would be much appreciated.
There is no difference between:
template <Float T>
and
template <typename T> requires Float<T>
They mean the same thing. If you declare a template and then define it later, you have to use the same syntax in both places - but both syntaxes do mean the same thing.
It's purely a matter of preference. The type-constraint syntax is more limited (can only be used to constrain a type) but can be more readable.
Note that the type-constraint syntax can express multi-type constraints. For instance the typical ranges pattern of:
template <typename I, typename S>
requires input_iterator<I>
and sentinel_for<S, I>
void algo(I, S);
can be written with the shorthand:
template <input_iterator I, sentinel_for<I> S>
void algo(I, S);