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_]