Description
Hi, folks.
We're implementing CWG2628 for Clang. While at it, we find the wording conjunction
in the sentence [over.match.class.deduct] is confusing as to whether we should read it the same way as that word used in concepts.
Specifically, consider the following example:
template <class> concept True = true;
template <class T> requires True<T> struct Y {
const int size;
template <class U>
constexpr Y(T, U(&)[3]) : size(sizeof(T)) {} // #1
};
template <typename T, typename U> Y(T, U (&)[3]) -> Y<U>; // #2
double arr3[3];
constexpr Y y(3, arr3); // #3
static_assert(y.size == 8); // ???
So there would be two viable CTAD guide candidates for the variable declaration at #3
: one is the explicit deduction defined at #2
, and the other is the synthesized deduction guide generated from #1
.
As per [over.match.class.deduct]p1.1.2, the associated constraints of the synthesized deduction guide should be the conjunction of the constraints on Y
and that of the constructor itself. So If we literally build up a conjunction for the synthesized guide, it would become into the following form:
template <typename T, typename U> requires True<T> Y(T, U (&)[3]) -> Y<T>;
Later in the overload resolution, this synthesized deduction guide would win because it is more constrained than #2
. So the static_assert doesn't hold because y.size
is now 4 rather than 8.
However, there is a footnote attached to [over.match.class.deduct]p1.1.2
:
A constraint-expression in the template-head of C is checked for satisfaction before any constraints from the template-head or trailing requires-clause of the constructor.
This seems to suggest we should check the constraint of C
(which is class template Y
in question) right before synthesizing the deduction guide for #1
. This is reasonable, but it is still unclear whether the constraint of C
, despite having been checked, should be propagated into the eventual deduction guide and thus affect the overload resolution. If not, would it make sense to clarify the intent there?