Open xmh0511 opened 1 year ago
Basing atomic constraint identity on the lexically enclosing declaration makes sense to me. However, if we only use the lexically enclosing declaration and not also "the same appearance of the same expression" then we will change behavior for examples such as this:
template<typename T, typename U, typename V> concept Z =
(A<T> && (sizeof(V) == 1)) || (A<U> && (sizeof(V) == 1));
Here, Z<A, B, C>
does not subsume Z<B, A, C>
nor vice versa, because the atomic constraints are not identical, but if we treated the two atomic constraints as identical because they are equivalent and appear within the same concept-definition, we would treat both as subsuming each other. So this is at least not an editorial change (though maybe CWG would be interested in it as an alternative rule).
I didn't understand the second part of the suggestion -- "those concepts whose constraint-expressions in their concept-definitions are identical. That sounds like it would cause these two concepts to be equivalent, which is not the design intent:
// Should be two distinct atomic constraints.
template<typename T> concept A = true;
template<typename T> concept B = true;
Here, Z<A, B, C> does not subsume Z<B, A, C> nor vice versa, because the atomic constraints are not identical
I think the subsequent wording of [temp.constr.atomic] p2 can cover this case:
given a hypothetical template A whose template-parameter-list consists of template-parameters corresponding and equivalent ([temp.over.link]) to those mapped by the parameter mappings of the expression, a template-id naming A whose template-arguments are the targets of the parameter mapping of e1 is the same ([temp.type]) as a template-id naming A whose template-arguments are the targets of the parameter mapping of e2.
A<T1, T2, T3>
is not the same as A<T2, T1, T3>
.
I didn't understand the second part of the suggestion -- "those concepts whose constraint-expressions in their concept-definitions are identical. That sounds like it would cause these two concepts to be equivalent, which is not the design intent:
I thought the wording could cover
template <unsigned N> constexpr bool Atomic = true;
template <unsigned N> concept C = Atomic<N>;
template <unsigned N> concept Add1 = C<N + 1>;
template <unsigned N> concept AddOne = C<N + 1>;
template <unsigned M> void f()
requires Add1<2 * M>;
template <unsigned M> int f()
requires AddOne<2 * M> && true;
Yes, the wording would accidentally cover
// Should be two distinct atomic constraints.
template<typename T> concept A = true;
template<typename T> concept B = true;
Which is not the intent of the standard.
Two atomic constraints, e1 and e2, are identical if and only if they are formed from the same concept and if, given a hypothetical template A...
This may be sufficient to cover the case
template<class T>
concept D = true;
template<typename T> concept A = D<T> && true;
template<typename T> concept B = D<T>;
The constraints formed from A<T>
and B<T>
would be X ∧ Y
and X
where X
is the same atomic constraint.
Full name of submitter (unless configured in github; will be published with the issue): Jim X
The original issue is in https://github.com/cplusplus/draft/issues/2554, which is tagged with CWG.
Consider such two contrasting examples:
After a bit of modification to this example:
In this example, the call is resolved to
#1
. However, in both examples, the atomic constraints are not formed from the same expressions. According to the grammarThe constraint-logical-or-expressions that are expressions in two declarations are different expressions.
Suggested resolution
As exposed in the first example, even though
std::is_same_v<T,A>
has the same sequence of tokens, the atomic constraints formed from them are not considered to be identical. As exposed in the second example, the atomic constraints formed fromsame_with_A<T>
are considered to be identical even thoughsame_with_A<T>
are in the different constraint-logical-or-expressions. Presumably, together with the examples in [temp.constr.atomic] example-1, the intent may want to say the atomic constraints are identical if and only if they are formed from the concepts whose constraint-expression are identical.