Skip to content

[over.match.class.deduct]p1.1.2 The wording "conjunction" is a bit confusing #7300

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

Closed
zyn0217 opened this issue Oct 12, 2024 · 4 comments
Closed

Comments

@zyn0217
Copy link

zyn0217 commented Oct 12, 2024

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?

@jensmaurer
Copy link
Member

Constraint satisfaction checking is order-sensitive. The note just emphasizes that the ordering is intentional here: first those of the class, then those of the constructor. But that's the natural outcome with the normative "conjunction" wording.

How do you read from the text that the checking should happen before the synthesis of the deduction guide for #1? How should that even work, given that T isn't known at this time?

@zyn0217
Copy link
Author

zyn0217 commented Oct 12, 2024

Oops, yes, I think I was going to say 'before that of #2', but my mind wandered at that moment :P

So... the provision there is actually saying, "just check the constraints as if they were a conjunction, but don't actually build up a conjunction form which might impact the overload resolution"? Is that correct?

@jensmaurer
Copy link
Member

No, the wording says you build the conjunction, including the effect on overload resolution (which means you prefer the implicit deduction guide over the explicit one in the example). I think that's a fall-out from the normative wording.

I don't think we have the notion anywhere in the language that you have a function template (same as deduction guide, overloading-wise) where you check some constraints, but don't consider them for partial ordering during overload resolution. If we wanted to invent such a novel mechanism, we surely wouldn't have hidden that under the "conjunction" wording, which clearly means "conjunction of constraints", with all consequences.

@zyn0217
Copy link
Author

zyn0217 commented Oct 14, 2024

Thanks for the clarification. I'll bring the takeaway to clang community.

@zyn0217 zyn0217 closed this as completed Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants