When refining concepts, the way it is consistently done in the standard is to fully write out the concept being refined. For instance, in [concepts.integral], SignedIntegral
refines Integral
like so:
template<class T>
concept Integral = is_integral_v<T>;
template<class T>
concept SignedIntegral = Integral<T> && is_signed_v<T>;
Why can't the refined concept be written as:
template<Integral T>
concept SignedIntegral2 = is_signed_v<T>;
SignedIntegral2
seems to have the same obvious meaning of SignedIntegral
, but it doesn't even compile on clang. Is there a reason for this?
The declaration of SignedIntegral2
is ill-formed because of [temp.concept]/4:
A concept shall not have associated constraints.
And it's important to understand the reason for this. Concepts are basically predicates. Their job is to take a series of arguments (most commonly, a series of types) and say whether the concept is satisfied or not. But consider what answer these two different implementations would give:
SignedIntegral<int32_t>
is true
SignedIntegral<uint32_t>
is false
SignedIntegral<string>
is false
But:
SignedIntegral2<int32_t>
is true
SignedIntegral2<uint32_t>
is false
SignedIntegral2<string>
is... undefinedThe whole point of concepts is to constrain. The proposed alternative, terse declaration in SignedIntegral2
constrains the type parameter T
to be Integral
. Since string
does not satisfy Integral
, we cannot even ask the question of if it's a SignedIntegral2
.
Put a different way, SignedIntegral
is a total function but SignedIntegral2
is a partial function that is only defined on Integral
types. This might be more clear if we write both to actually be functions:
template <typename T>
constexpr bool SignedIntegral() { return Integral<T> && is_signed_v<T>; }
template <Integral T>
constexpr bool SignedIntegral2() { return is_signed_v<T>; }
It is important that concepts always be total functions, which is why associated constraints are disallowed.
Note that it is surely possible as an extension to treat "undefined" as false
for the purposes of concepts satisfaction, but this would add extra wrinkles to the subsumption rules and it's surely non-trivial implementation complexity. It's certainly possible that some future standard might allow them. My crystal ball is currently at the shop, so I can't say for sure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With