Created on 2022-12-05.00:00:00 last changed 16 months ago
Proposed resolution (approved by CWG 2023-02-09):
Change in 12.2.2.9 [over.match.class.deduct] paragraph 3 as follows:
... For each function or function template f in the guides of the template named by the simple-template-id of the defining-type-id, the template arguments of the return type of f are deduced from the defining-type-id of A according to the process in 13.10.3.6 [temp.deduct.type] with the exception that deduction does not fail if not all template arguments are deduced. If deduction fails for another reason, proceed with an empty set of deduced template arguments Let g denote the result of substituting these deductions into f. ...
CWG 2023-02-08
In the example, A is the most trivial alias template imaginable; having this cause issues depending on the details of C is concerning.
Suggested resolution:
We could say that cases where P involves a template parameter and A is not of the same form (under 13.10.3.6 [temp.deduct.type] paragraph 8) are non-deduced contexts for the purpose of these deductions. That should be enough to make it clear what happens for a2, where we'd deduce T2 = V2, and not deduce anything for T1, but wouldn't fix a1 due to the inconsistent deductions for T1; maybe this is what MSVC is doing. We could further fix a1 by allowing inconsistent deductions and treating them as if no value was deduced. Another option might be to do independent deductions for each template argument of the simple-template-id, and then try to merge the results for template arguments where deduction was successful; that'd be clearer that deduction can't fail, but would deduce less.
[Accepted as a DR at the February, 2023 meeting.]
Subclause 12.2.2.9 [over.match.class.deduct] paragraph 3 has an exception only for deduction failure for non-deduced contexts when deducing the return type from the defining-type-id, but not for other cases where deduction fails according to 13.10.3.6 [temp.deduct.type] paragraph 2. For example,
template <class S1, class S2> struct C { C(...); }; template<class T1> C(T1) -> C<T1, T1>; template<class T1, class T2> C(T1, T2) -> C<T1 *, T2>; template<class V1, class V2> using A = C<V1, V2>; C c1{""}; A a1{""}; C c2{"", 1}; A a2{"", 1};
resulting in A having neither of these deduction guides. There is implementation divergence in the handling of this example.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-07-16 13:00:43 | admin | set | status: open -> c++23 |
2023-07-16 13:00:43 | admin | set | status: dr -> open |
2023-02-18 18:43:04 | admin | set | status: ready -> dr |
2023-02-10 23:01:52 | admin | set | status: tentatively ready -> ready |
2023-02-10 03:08:38 | admin | set | messages: + msg7183 |
2023-02-10 03:08:38 | admin | set | status: open -> tentatively ready |
2023-02-09 02:52:21 | admin | set | messages: + msg7178 |
2022-12-05 20:38:28 | admin | set | messages: + msg7091 |
2022-12-05 00:00:00 | admin | create |