-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concepts that use type traits are inadvertently subsuming them #321
Comments
Proposed ResolutionChange [concepts.lib.corelang.same] as follows: template <class T, class U>
concept bool Same() {
- return see below ;
+ return is_same<T, U>::value; // see below
}
-1 Same<T, U>() is satisfied if and only if T and U denote the same
- type.
+1 There need not be any subsumption relationship between Same<T, U>() and
+ is_same<T, U>::value.
2 Remarks: For the purposes of constraint checking, Same<T, U>()
implies Same<U, T>(). Change [concepts.lib.corelang.derived] as suggested in #255. Change [concepts.lib.corelang.convertibleto] as suggested in #167. Change [concepts.lib.corelang.integral] as follows: template <class T>
concept bool Integral() {
- return is_integral<T>::value;
+ return is_integral<T>::value; // see below
}
+1 There need not be any subsumption relationship between Integral<T>() and
+ is_integral<T>::value. Change [concepts.lib.corelang.signedintegral] as follows: template <class T>
concept bool SignedIntegral() {
- return Integral<T>() && is_signed<T>::value;
+ return Integral<T>() && is_signed<T>::value; // see below
}
+1 There need not be any subsumption relationship between SignedIntegral<T>()
+ and is_signed<T>::value. |
That doesn't hide the subsumption, it makes the concept subsume a different (and weird) predicate constraint. |
Redirect-through-an-unnamable-trait looks like: +template <class T, class U>
+constexpr bool __same = is_same<T, U>::value; // exposition only
template <class T, class U>
concept bool Same() {
- return see below ;
+ return __same<T, U>;
}
-1 Same<T, U>() is satisfied if and only if T and U denote the same type.
2 Remarks: For the purposes of constraint checking, Same<T, U>()
implies Same<U, T>(). +template <class T>
+constexpr bool __integral = is_integral<T>::value; // exposition only
template <class T>
concept bool Integral() {
- return is_integral<T>::value;
+ return __integral<T>;
} +template <class T>
+constexpr bool __signed = is_signed<T>::value; // exposition only
template <class T>
concept bool SignedIntegral() {
- return Integral<T>() && is_signed<T>::value;
+ return Integral<T>() && __signed<T>;
} It needs more syntax, but avoids naming an exact predicate constraint that users can get a handle on for subsumption. |
Can we get away with: template <class T, class U>
concept bool Same() {
- return see below ;
+ return is_same<T, U>::value; // see below
}
-1 Same<T, U>() is satisfied if and only if T and U denote the same type.
+1 There is no subsumption relationship between Same<T, U>() and is_same<T, U>::value.
2 Remarks: For the purposes of constraint checking, Same<T, U>()
implies Same<U, T>(). |
Yes - that's a good way to avoid increasing specification complexity for this small issue. |
LWG prefers to word these as "There need not be any subsumption relationship.." (PR edited in place with that phrasing.) |
In many cases, implementors may want the freedom to implement the concepts directly in terms of the compiler intrinsics that are used to implement the traits. However, by specifying the concepts directly in terms of the type traits, we create a subsumption relationship between the concept and the trait. Implementations no longer have the freedom to not use the trait because that has observable effects on overload resolution.
We propose eliminating the subsumption relationships, thereby giving implementors the freedom to innovate under the as-if rule.
This can be done trivially by double-negating the type trait, thereby hiding the subsumption relationship.The text was updated successfully, but these errors were encountered: