[over.match.class.deduct]

# 12 Overloading [[over]](./#over)

## 12.2 Overload resolution [[over.match]](over.match#class.deduct)

### 12.2.2 Candidate functions and argument lists [[over.match.funcs]](over.match.funcs#over.match.class.deduct)

#### 12.2.2.9 Class template argument deduction [over.match.class.deduct]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1221)

When resolving a placeholder for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8 Deduced class template specialization types"))
where the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]") designates a primary class template C,
a set of functions and function templates, called the guides of C,
is formed comprising:

- [(1.1)](#1.1)

  If C is defined,
for each constructor of C,
a function template with the following properties:
  * [(1.1.1)](#1.1.1)

      The template parameters are the template parameters of C followed
by the template parameters (including default template arguments) of the constructor,
if any[.](#1.1.1.sentence-1)

  * [(1.1.2)](#1.1.2)

      The associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")) are the conjunction of
the associated constraints of C and
the associated constraints of the constructor, if any[.](#1.1.2.sentence-1)
      [*Note [1](#note-1)*:
      A [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") in
the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") of C is checked for satisfaction before any constraints from
the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") or trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of the constructor[.](#1.1.2.sentence-2)
 â *end note*]

  * [(1.1.3)](#1.1.3)

      The [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is that of the constructor[.](#1.1.3.sentence-1)

  * [(1.1.4)](#1.1.4)

      The return type is the class template specialization
designated by C and template arguments
corresponding to the template parameters of C[.](#1.1.4.sentence-1)

- [(1.2)](#1.2)

  If C is not defined or does not declare any constructors,
an additional function template derived as above
from a hypothetical constructor C()[.](#1.2.sentence-1)

- [(1.3)](#1.3)

  An additional function template derived as above
from a hypothetical constructor C(C),
called the [*copy deduction candidate*](#def:copy_deduction_candidate "12.2.2.9 Class template argument deduction [over.match.class.deduct]")[.](#1.3.sentence-1)

- [(1.4)](#1.4)

  For each [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]"),
a function or function template
with the following properties:
  * [(1.4.1)](#1.4.1)

      The [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]"), if any,
and [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") are those of the [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]")[.](#1.4.1.sentence-1)

  * [(1.4.2)](#1.4.2)

      The return type
is the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") of the [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]")[.](#1.4.2.sentence-1)

In addition, if C is defined
and its definition satisfies the conditions for
an aggregate class ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates"))
with the assumption that any dependent base class has
no virtual functions and no virtual base classes, and
the initializer is a non-empty [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") or
parenthesized [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]"), and
there are no [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]")*s* for C,
the set contains an additional function template,
called the [*aggregate deduction candidate*](#def:candidate,aggregate_deduction "12.2.2.9 Class template argument deduction [over.match.class.deduct]"), defined as follows[.](#1.sentence-2)

Let x1,â¦,xn be the elements
of the [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") or[*designated-initializer-list*](dcl.init.general#nt:designated-initializer-list "9.5.1 General [dcl.init.general]") of the [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]"), or
of the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")[.](#1.sentence-3)

For each xi, let ei be the corresponding aggregate element
of C or of one of its (possibly recursive) subaggregates
that would be initialized by xi ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")) if

- [(1.5)](#1.5)

brace elision is not considered for any aggregate element
that has
  * [(1.5.1)](#1.5.1)

a dependent non-array type,

  * [(1.5.2)](#1.5.2)

an array type with a value-dependent bound, or

  * [(1.5.3)](#1.5.3)

an array type with a dependent array element type and xi is a string literal; and

- [(1.6)](#1.6)

each non-trailing aggregate element that is a pack expansion
is assumed to correspond to no elements of the initializer list, and

- [(1.7)](#1.7)

a trailing aggregate element that is a pack expansion is assumed to correspond
to all remaining elements of the initializer list (if any)[.](#1.sentence-4)

If there is no such aggregate element ei for any xi,
the aggregate deduction candidate is not added to the set[.](#1.sentence-5)

The aggregate deduction candidate is derived as above
from a hypothetical constructor C(T1,â¦,Tn),
where

- [(1.8)](#1.8)

if ei is of array type andxi is a [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]"),Ti is an rvalue reference to the declared type of ei, and

- [(1.9)](#1.9)

if ei is of array type andxi is a [*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]"),Ti is an lvalue reference to
the const-qualified declared type of ei, and

- [(1.10)](#1.10)

otherwise, Ti is the declared type of ei,

except that additional parameter packs of the form Pj... are inserted into the parameter list in their original aggregate element position corresponding to each non-trailing aggregate element of type Pj that was skipped because it was a parameter pack, and
the trailing sequence of parameters corresponding
to a trailing aggregate element that is a pack expansion (if any)
is replaced by a single parameter of the form Tn...[.](#1.sentence-6)

In addition,
if C is defined and
inherits constructors ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))
from a direct base class denoted in the [*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]") by a [*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]") B,
let A be an alias template
whose template parameter list is that of C and
whose [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") is B[.](#1.sentence-7)

If A is a deducible template ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers")),
the set contains the guides of A with the return type R of each guide
replaced with typename CC<R>​::​type given a class templatetemplate <typename> class CC; whose primary template is not defined and
with a single partial specialization
whose template parameter list is that of A and
whose template argument list is a specialization of A with
the template argument list of A ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types"))
having a member typedef type designating a template specialization with
the template argument list of A but
with C as the template[.](#1.sentence-8)

[*Note [2](#note-2)*:

Equivalently,
the template parameter list of the specialization is that of C,
the template argument list of the specialization is B, and
the member typedef names C with the template argument list of C[.](#1.sentence-9)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1373)

[*Example [1](#example-1)*: template <typename T> struct B { B(T);};template <typename T> struct C : public B<T> {using B<T>::B;};template <typename T> struct D : public B<T> {};

C c(42); // OK, deduces C<int> D d(42); // error: deduction failed, no inherited deduction guides B(int) -> B<char>;
C c2(42); // OK, deduces C<char>template <typename T> struct E : public B<int> {using B<int>::B;};

E e(42); // error: deduction failed, arguments of E cannot be deduced from introduced guidestemplate <typename T, typename U, typename V> struct F { F(T, U, V);};template <typename T, typename U> struct G : F<U, T, int> {using G::F::F;} G g(true, 'a', 1); // OK, deduces G<char, bool>template<class T, std::size_t N>struct H { T array[N];};template<class T, std::size_t N>struct I {volatile T array[N];};template<std::size_t N>struct J {unsigned char array[N];};

H h = { "abc" }; // OK, deduces H<char, 4> (not T = const char) I i = { "def" }; // OK, deduces I<char, 4> J j = { "ghi" }; // error: cannot bind reference to array of unsigned char to array of char in deduction â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1423)

When resolving a placeholder for a deduced class type ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"))
where
the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]") designates an alias template A,
the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") of A must be of the form

typenameopt [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")

as specified in [[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers")[.](#3.sentence-1)

The guides of A are the set of functions or function templates
formed as follows[.](#3.sentence-2)

For each function or function template f in the guides of
the template named by the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") of the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]"),
the template arguments of the return type of f are deduced
from the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") of A according to the process in [[temp.deduct.type]](temp.deduct.type "13.10.3.6 Deducing template arguments from a type") with the exception that deduction does not fail
if not all template arguments are deduced[.](#3.sentence-3)

If deduction fails for another reason,
proceed with an empty set of deduced template arguments[.](#3.sentence-4)

Let g denote the result of substituting
these deductions into f[.](#3.sentence-5)

If substitution succeeds,
form a function or function template f' with the following properties and add it to the set
of guides of A:

- [(3.1)](#3.1)

  The function type of f' is the function type of g[.](#3.1.sentence-1)

- [(3.2)](#3.2)

  If f is a function template,f' is a function template whose
template parameter list consists of
all the template parameters of A (including their default template arguments)
that appear in the above deductions or
(recursively) in their default template arguments,
followed by the template parameters of f that were not deduced
(including their default template arguments),
otherwise f' is not a function template[.](#3.2.sentence-1)

- [(3.3)](#3.3)

  The associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")) are
the conjunction of the associated constraints of g and
a constraint that is satisfied if and only if
the arguments of A are deducible (see below) from the return type[.](#3.3.sentence-1)

- [(3.4)](#3.4)

  If f is a copy deduction candidate,
then f' is considered to be so as well[.](#3.4.sentence-1)

- [(3.5)](#3.5)

  If f was generated
from a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]") ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3 Deduction guides")),
then f' is considered to be so as well[.](#3.5.sentence-1)

- [(3.6)](#3.6)

  The [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]") of f' is
the [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]") of g (if any)[.](#3.6.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1489)

The arguments of a template A are said to be
deducible from a type T if, given a class templatetemplate <typename> class AA; with a single partial specialization
whose template parameter list is that of A and
whose template argument list is a specialization of A with the template argument list of A ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")),AA<T> matches the partial specialization[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1501)

Initialization and overload resolution are performed as described
in [[dcl.init]](dcl.init "9.5 Initializers") and [[over.match.ctor]](over.match.ctor "12.2.2.4 Initialization by constructor"), [[over.match.copy]](over.match.copy "12.2.2.5 Copy-initialization of class by user-defined conversion"),
or [[over.match.list]](over.match.list "12.2.2.8 Initialization by list-initialization") (as appropriate for the type of initialization
performed) for an object of a hypothetical class type, where
the guides of the template named by the placeholder are considered to be the
constructors of that class type for the purpose of forming an overload
set, and the initializer is provided by the context in which class
template argument deduction was performed[.](#5.sentence-1)

The following exceptions apply:

- [(5.1)](#5.1)

  The first phase in [[over.match.list]](over.match.list "12.2.2.8 Initialization by list-initialization") (considering initializer-list constructors)
is omitted if the initializer list consists of
a single expression of type cv U,
where U is, or is derived from,
a specialization of the class template
directly or indirectly named by the placeholder[.](#5.1.sentence-1)

- [(5.2)](#5.2)

  During template argument deduction for the aggregate deduction candidate,
the number of elements in a trailing parameter pack
is only deduced from the number of remaining function arguments
if it is not otherwise deduced[.](#5.2.sentence-1)

If the function or function template was generated from
a constructor or [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]") that had an [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]"),
each such notional constructor is considered to have
that same [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]")[.](#5.sentence-3)

All such notional constructors are considered to be
public members of the hypothetical class type[.](#5.sentence-4)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1534)

[*Example [2](#example-2)*: template <class T> struct A {explicit A(const T&, ...) noexcept; // #1 A(T&&, ...); // #2};

int i;
A a1 = { i, i }; // error: explicit constructor #1 selected in copy-list-initialization during deduction,// cannot deduce from non-forwarding rvalue reference in #2 A a2{i, i}; // OK, #1 deduces to A<int> and also initializes A a3{0, i}; // OK, #2 deduces to A<int> and also initializes A a4 = {0, i}; // OK, #2 deduces to A<int> and also initializestemplate <class T> A(const T&, const T&) -> A<T&>; // #3template <class T> explicit A(T&&, T&&) -> A<T>; // #4 A a5 = {0, 1}; // error: explicit deduction guide #4 selected in copy-list-initialization during deduction A a6{0,1}; // OK, #4 deduces to A<int> and #2 initializes A a7 = {0, i}; // error: #3 deduces to A<int&>, #1 and #2 declare same constructor A a8{0,i}; // error: #3 deduces to A<int&>, #1 and #2 declare same constructortemplate <class T> struct B {template <class U> using TA = T; template <class U> B(U, TA<U>);};

B b{(int*)0, (char*)0}; // OK, deduces B<char*>template <typename T>struct S { T x;
 T y;};

template <typename T>struct C { S<T> s;
 T t;};

template <typename T>struct D { S<int> s;
 T t;};

C c1 = {1, 2}; // error: deduction failed C c2 = {1, 2, 3}; // error: deduction failed C c3 = {{1u, 2u}, 3}; // OK, deduces C<int> D d1 = {1, 2}; // error: deduction failed D d2 = {1, 2, 3}; // OK, braces elided, deduces D<int>template <typename T>struct E { T t; decltype(t) t2;};

E e1 = {1, 2}; // OK, deduces E<int>template <typename... T>struct Types {};

template <typename... T>struct F : Types<T...>, T... {};

struct X {};struct Y {};struct Z {};struct W { operator Y(); };

F f1 = {Types<X, Y, Z>{}, {}, {}}; // OK, F<X, Y, Z> deduced F f2 = {Types<X, Y, Z>{}, X{}, Y{}}; // OK, F<X, Y, Z> deduced F f3 = {Types<X, Y, Z>{}, X{}, W{}}; // error: conflicting types deduced; operator Y not considered â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/overloading.tex#L1615)

[*Example [3](#example-3)*: 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>>; // #2template<class V> using A = C<V *, V *>;template<std::[integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") W> using B = A<W>;

int i{};double d{};
A a1(&i, &i); // deduces A<int> A a2(i, i); // error: cannot deduce V * from i A a3(&i, &d); // error: #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); // error: 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 templatetemplate<class T, class 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 from the deduction-guide #2 of Ctemplate<class T, class U> auto f2(T, U) -> C<T, std::type_identity_t<U>>;

// Deducing arguments for C<T, std​::​type_identity_t<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 f1' and f2' for A are as follows:template<std::[integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") 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](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]") 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*]
