Deduction failure in CTAD for alias templates
Section [over.match.class.deduct]
Christof Meerwald

Created on 2022-12-05.00:00:00 last changed 4 months ago


Date: 2023-02-10.03:08:38

Proposed resolution (approved by CWG 2023-02-09):

Change in [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 [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. ...
Date: 2023-02-09.02:52:21

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.

Date: 2022-12-05.20:38:28

Suggested resolution:

We could say that cases where P involves a template parameter and A is not of the same form (under [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.

Date: 2023-02-15.00:00:00

[Accepted as a DR at the February, 2023 meeting.]

Subclause [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 [temp.deduct.type] paragraph 2. For example,

  template <class S1, class S2> struct 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.

Date User Action Args
2023-07-16 13:00:43adminsetstatus: open -> c++23
2023-07-16 13:00:43adminsetstatus: dr -> open
2023-02-18 18:43:04adminsetstatus: ready -> dr
2023-02-10 23:01:52adminsetstatus: tentatively ready -> ready
2023-02-10 03:08:38adminsetmessages: + msg7183
2023-02-10 03:08:38adminsetstatus: open -> tentatively ready
2023-02-09 02:52:21adminsetmessages: + msg7178
2022-12-05 20:38:28adminsetmessages: + msg7091
2022-12-05 00:00:00admincreate