CTAD for alias templates and the deducible check
Section [over.match.class.deduct]
Richard Smith

Created on 2019-08-12.00:00:00 last changed 17 months ago


Date: 2019-08-12.00:00:00

Given the declarations

  template<typename T = int> using X = vector<int>;
  X x = {1, 2, 3};

  template<typename...> using Y = vector<int>;
  Y y = {1, 2, 3};

CTAD deduces vector<int>. Then we are asked to perform a check that the arguments of X and Y are deducible from vector<int>.

I think this check should succeed, deducing T = int in the first case and <pack> = <empty> in the second case, so both declarations should be valid. That seems consistent with what would happen for a non-alias with template parameters that CTAD can't deduce, where there is either a default template argument or the parameter is a pack. But what actually happens is that we're asked to form

  template<typename T> struct AA;
  template<typename T = int> struct AA<X<T>>;


  template<typename T> struct AA;
  template<typename ...Ts> struct AA<Y<Ts...>>;

However, both of those partial specializations are ill-formed: a partial specialization can't have default template arguments, and neither of these is more specialized than the primary template, because T / Ts are not used in deducible contexts.

I think we have the wrong model here, and should instead be considering (effectively) whether function template argument deduction would succeed for

  template<typename T> struct AA {};
  template<typename T = int> void f(AA<X<T>>);


  template<typename T> struct AA {};
  template<typename ...Ts> void f(AA<Y<Ts...>>);

respectively, when given an argument of type AA<deduced return type>. That is, get rid of the weird class template partial specialization restrictions, and instead add in the rules from function templates to use default template arguments and to default non-deduced packs to empty packs.

Date User Action Args
2019-08-12 00:00:00admincreate