ecatmur
ecatmur

Reputation: 157344

Ad-hoc constraint requires requires requires requires?

Suppose I'm writing a class template some of whose members are constrained on the presence and value of a type template parameter static constexpr data member:

template<class T>
struct A {
    constexpr bool operator()() requires T::value { return T::value; }
    constexpr bool operator()() { return false; }
};
#include <type_traits>
static_assert(A<std::true_type>()());
static_assert(!A<std::false_type>()());
static_assert(!A<void>()());

MSVC and gcc accept this, but clang rejects unless I replace requires T::value with requires requires { requires T::value; }. Is this a bug in clang, or are the other compilers lax; is it the case that C++ requires requires requires requires? What does the Standard say?

Related (well, ⅔ at least): Why do we require requires requires?

Upvotes: 6

Views: 493

Answers (1)

Barry
Barry

Reputation: 302932

This is a clang bug (submitted #49513).

It looks like clang is substituting void into T::value and deciding that because that's an invalid expression, that the constraint is invalid. But the rule, in [temp.constr.atomic] is that:

To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied.

In this case, substitution results in an invalid type or expression, so the result of that should be that the constraint is not satisfied.


Note that this overload:

constexpr bool operator()() requires T::value { return T::value; }

is only valid if T::value is a valid expression and evaluates to true. Which makes it equivalent to this:

constexpr bool operator()() requires T::value { return true; }

Which is fine in this case, since you're returning false in the other case anyway, so there's no reason to distinguish T::value exists but is false from T::value does not exist.

But thought it was worth clarifying anyway.

Upvotes: 4

Related Questions