I'm reading Josuttis' C++20 the Complete Guide, and I think I've absorbed that a clause like the one in the template below

template<typename T>
requires requires { typename std::remove_const_t<T>; }
…

is completely useless as it resolves to requires true because remove_const_t always returns a type when given a type.

However, I reasoned, that's not the case, for instance, for enable_if, so I came up with

requires { typename std::enable_if_t<std::is_integral_v<T>>; }

Now, since the requires expression simply checks that the requirements in the {…} are well-formed, I think that's basically what the following does

std::is_integral_v<T>

It seems pretty uncontroversial to me, but I'm asking because I'm new to C++ concepts and it is perfectly possible that I'm making a mistake.

1

There are 1 best solutions below

1
LoS On

The two expressions have the same effect as, in this case, the requires is a boolean expression itself.

Specifically, the first expression works as std::enable_if is implemented in the following way:

template<bool B, class T = void>
struct enable_if {};
 
template<class T>
struct enable_if<true, T> { typedef T type; };

When the fun_v<T> is true, the template partial-specialization is used, and the requires-expression is satisfied, since it simply verifies whether type is well-formed. Likewise, when the fun_v<T> is false, the first template is used, and the requires-expression is not satisfied, since type is not well-formed.