Wording for Class Template Argument Deduction for Alias Templates (original) (raw)

[Example:

template <class T, class U> struct C {
  C(T, U);   // #1
};
template<class T, class U>
C(T, U) -> C<T, std::type_identity_t<U>>; // #2

template<class V>
using A = C<V *, V *>;
    template<std::Integral W>
    using B = A<W>;

int i{};
double d{};
A a1(&i, &i); // Deduces _A<int>_
A a2(i, i);   // _Ill-formed: cannot deduce V * from i_
A a3(&i, &d); // _Ill-formed: #1: Cannot deduce (V*, V*) from (int *, double *)_ 
                              // #2: Cannot deduce A<V> from C<int *, double *>
    B b1(&i, &i); // Deduces B<int>
    B b2(&d, &d); // Ill-formed: cannot deduce B<W> from C<double *, double *>

Possible exposition only implementation of the above procedure:

    //_The following concept ensures a specialization of A is deduced_
    template <class> class AA;
    template <class V> class AA<A<V>> { };
    template <class T> concept deduces_A = requires { sizeof(AA<T>); };

    // _f1 is formed from the constructor #1 of C_
    // _generating the following function template_
    template<T, U>
    auto f1(T, U) -> C<T, U>;

    // _Deducing arguments for C<T, U> from C<V *, V*> deduces T as V * and U as V *_
    
    // _f1'_ is obtained by transforming f1 as described by the above procedure
    template<class V> requires deduces_A<C<V *, V *>>
  auto f1_prime(V *, V*) -> C<V *, V *>;

    // _f2 is formed the deduction-guide #2 of C_
    template<class T, class U> auto f2(T, U) -> C<T, std::type_identity_t<U>>;

    // _Deducing arguments for C<T, std::typeidentityt<U>> from C<V *, V*> deduces T as V *_

// _f2' is obtained by transforming f2 as described by the above procedure_
template<class V, class U> 
      requires deduces_A<C<V *, std::type_identity_t<U>>>
auto f2_prime(V *, U) -> C<V *, std::type_identity_t<U>>;
          

    // _The following concept ensures a specialization of B is deduced_
    template <class> class BB;
    template <class V> class BB<B<V>> { };
    template <class T> concept deduces_B = requires { sizeof(BB<T>); };
    
    // The guides for B derived from the above f' and f1' for A are
    template<std::Integral W>
  requires deduces_A<C<W *, W *>>
            && deduces_B<C<W *, W *>>
auto f1_prime_for_B(W *, W *) -> C<W *, W *>;

 template<std::Integral W, class U> 
  requires deduces_A<C<W *, std::type_identity_t<U>>>
            && deduces_B<C<W *, std::type_identity_t<U>>>
auto f2_prime_for_B(W *, U) -> C<W *, std::type_identity_t<U>>;
        

_— end example_]