3

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.

Enlico
  • 23,259
  • 6
  • 48
  • 102
  • Are you asking about the difference between them as constraints with `requires`? Or is there a difference anywhere? – 康桓瑋 Mar 04 '23 at 13:36
  • @康桓瑋, I'm asking if changing `fun_v` to `requires { typename enable_if_t>; }` is supposed to generate the same program for any possible `template inline constexpr bool fun_v = fun::value;` – Enlico Mar 04 '23 at 13:44

1 Answers1

0

It works because std::enable_if is implemented as follows:

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 second template is used and the constraint is satisfied, since it simply checks if type is well-formed (in this case, it must simply exist, and does not matter if it is defined as void or something else), and likewise, when the fun_v<T> is false, the first template is used and the constraint is not satisfied, since type is not well-formed.

So, you can use std::enable_if to create a constraint in this way, but it is nonsense. In fact, if you read the information about what is std::enable_if, you will find this sentence: "This metafunction is a convenient way to leverage SFINAE prior to C++20's concepts, in particular for conditionally removing functions from the candidate set based on type traits, allowing separate function overloads or specializations based on those different type traits". Then, there is no sense to mix SFINAE and C++20's concepts.

LoS
  • 448
  • 1
  • 3
  • 15
  • Nowhere in my question I've referred to actually using that nonsense. I've just asked if the two expression have precisely the same effect. – Enlico Mar 04 '23 at 13:26
  • @Enlico, I have adjusted my answer according to your feedback. – LoS Mar 04 '23 at 16:07