Skip to content

Commit 1bac4eb

Browse files
authored
Merge 2019-07 CWG Motion 21
P1814R0 Class template argument deduction for alias template Fixes #3001.
2 parents d4dc044 + 6552c03 commit 1bac4eb

File tree

4 files changed

+155
-7
lines changed

4 files changed

+155
-7
lines changed

source/declarations.tex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,16 @@
13841384
\opt{\tcode{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name}
13851385
is a placeholder for
13861386
a deduced class type\iref{dcl.type.class.deduct}.
1387-
The \grammarterm{template-name} shall name a class template.
1387+
The \grammarterm{nested-name-specifier}, if any, shall be non-dependent and
1388+
the \grammarterm{template-name} shall name a deducible template.
1389+
A \defnadj{deducible}{template} is either a class template or
1390+
is an alias template whose \grammarterm{defining-type-id} is of the form
1391+
\begin{ncsimplebnf}
1392+
\opt{\keyword{typename}} \opt{nested-name-specifier} \opt{\keyword{template}} simple-template-id
1393+
\end{ncsimplebnf}
1394+
where the \grammarterm{nested-name-specifier} (if any) is non-dependent and
1395+
the \grammarterm{template-name} of the \grammarterm{simple-template-id}
1396+
names a deducible template.
13881397
\begin{note}
13891398
An injected-class-name is never interpreted as a \grammarterm{template-name}
13901399
in contexts where class template argument deduction would be performed\iref{temp.local}.

source/overloading.tex

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,8 @@
14991499
\pnum
15001500
When resolving a placeholder for a deduced class type\iref{dcl.type.class.deduct}
15011501
where the \grammarterm{template-name} names a primary class template \tcode{C},
1502-
a set of functions and function templates is formed comprising:
1502+
a set of functions and function templates, called the guides of \tcode{C},
1503+
is formed comprising:
15031504
\begin{itemize}
15041505
\item
15051506
If \tcode{C} is defined,
@@ -1569,21 +1570,96 @@
15691570
from a hypothetical constructor $\tcode{C}(\tcode{T}_1, \dotsc, \tcode{T}_n)$,
15701571
where $\tcode{T}_i$ is the declared type of the element $e_i$.
15711572

1573+
\pnum
1574+
When resolving a placeholder for a deduced class type\iref{dcl.type.simple}
1575+
where the \grammarterm{template-name} names an alias template \tcode{A},
1576+
the \grammarterm{defining-type-id} of \tcode{A} must be of the form
1577+
\begin{ncsimplebnf}
1578+
\opt{\keyword{typename}} \opt{nested-name-specifier} \opt{\keyword{template}} simple-template-id
1579+
\end{ncsimplebnf}
1580+
as specified in \ref{dcl.type.simple}.
1581+
The guides of \tcode{A} are the set of functions or function templates
1582+
formed as follows.
1583+
For each function or function template \tcode{f} in the guides of
1584+
the template named by the \grammarterm{simple-template-id}
1585+
of the \grammarterm{defining-type-id},
1586+
the template arguments of the return type of \tcode{f}
1587+
are deduced
1588+
from the \grammarterm{defining-type-id} of \tcode{A}
1589+
according to the process in \ref{temp.deduct.type}
1590+
with the exception that deduction does not fail
1591+
if not all template arguments are deduced.
1592+
Let \tcode{g} denote the result of substituting
1593+
these deductions into \tcode{f}.
1594+
If substitution succeeds,
1595+
form a function or function template \tcode{f'}
1596+
with the following properties and add it to the set
1597+
of guides of \tcode{A}:
1598+
\begin{itemize}
1599+
\item
1600+
The function type of \tcode{f'} is the function type of \tcode{g}.
1601+
1602+
\item
1603+
If \tcode{f} is a function template,
1604+
\tcode{f'} is a function template whose
1605+
template parameter list consists of
1606+
all the template parameters of \tcode{A}
1607+
(including their default template arguments)
1608+
that appear in the above deductions or
1609+
(recursively) in their default template arguments,
1610+
followed by the template parameters of \tcode{f} that were not deduced
1611+
(including their default template arguments),
1612+
otherwise \tcode{f'} is not a function template.
1613+
1614+
\item
1615+
The associated constraints\iref{temp.constr.decl} are
1616+
the conjunction of the associated constraints of \tcode{g} and
1617+
a constraint that is satisfied if and only if
1618+
the arguments of \tcode{A} are deducible (see below) from the return type.
1619+
1620+
\item
1621+
If \tcode{f} is a copy deduction candidate\iref{over.match.class.deduct},
1622+
then \tcode{f'} is considered to be so as well.
1623+
1624+
\item
1625+
If \tcode{f} was generated
1626+
from a \grammarterm{deduction-guide}\iref{over.match.class.deduct},
1627+
then \tcode{f'} is considered to be so as well.
1628+
1629+
\item
1630+
The \grammarterm{explicit-specifier} of \tcode{f'} is
1631+
the \grammarterm{explicit-specifier} of \tcode{g} (if any).
1632+
\end{itemize}
1633+
1634+
\indextext{template!deducible arguments of}%
1635+
\pnum
1636+
The arguments of a template \tcode{A} are said to be
1637+
deducible from a type \tcode{T} if, given a class template
1638+
\begin{codeblock}
1639+
template <typename> class AA;
1640+
\end{codeblock}
1641+
with a single partial specialization
1642+
whose template parameter list is that of \tcode{A} and
1643+
whose template argument list is a specialization of \tcode{A}
1644+
with the template argument list of \tcode{A}\iref{temp.dep.type},
1645+
\tcode{AA<T>} matches the partial specialization.
1646+
15721647
\pnum
15731648
Initialization and overload resolution are performed as described
15741649
in \ref{dcl.init} and \ref{over.match.ctor}, \ref{over.match.copy},
15751650
or \ref{over.match.list} (as appropriate for the type of initialization
15761651
performed) for an object of a hypothetical class type, where
1577-
the selected functions and function templates are considered to be the
1652+
the guides of the template named by the placeholder are considered to be the
15781653
constructors of that class type for the purpose of forming an overload
15791654
set, and the initializer is provided by the context in which class
15801655
template argument deduction was performed.
15811656
As an exception, the first phase in \ref{over.match.list}
15821657
(considering initializer-list constructors)
15831658
is omitted if the initializer list consists of
15841659
a single expression of type \cv{}~\tcode{U},
1585-
where \tcode{U} is a specialization of \tcode{C} or
1586-
a class derived from a specialization of \tcode{C}.
1660+
where \tcode{U} is a specialization of the class template
1661+
for which the placeholder names a specialization or
1662+
a class derived therefrom.
15871663
If the function or function template was generated from
15881664
a constructor or \grammarterm{deduction-guide}
15891665
that had an \grammarterm{explicit-specifier},
@@ -1661,6 +1737,69 @@
16611737

16621738
E e1 = {1, 2}; // OK, \tcode{E<int>} deduced
16631739
\end{codeblock}
1740+
\end{example}
1741+
1742+
\pnum
1743+
\begin{example}
1744+
\begin{codeblock}
1745+
template <class T, class U> struct C {
1746+
C(T, U); // \#1
1747+
};
1748+
template<class T, class U>
1749+
C(T, U) -> C<T, std::type_identity_t<U>>; // \#2
1750+
1751+
template<class V> using A = C<V *, V *>;
1752+
template<std::Integral W> using B = A<W>;
1753+
1754+
int i{};
1755+
double d{};
1756+
A a1(&i, &i); // deduces \tcode{A<int>}
1757+
A a2(i, i); // error: cannot deduce \tcode{V *} from \tcode{i}
1758+
A a3(&i, &d); // error: \#1: cannot deduce \tcode{(V*, V*)} from \tcode{(int *, double *)}
1759+
// \#2: cannot deduce \tcode{A<V>} from \tcode{C<int *, double *>}
1760+
B b1(&i, &i); // deduces \tcode{B<int>}
1761+
B b2(&d, &d); // error: cannot deduce \tcode{B<W>} from \tcode{C<double *, double *>}
1762+
\end{codeblock}
1763+
Possible exposition-only implementation of the above procedure:
1764+
\begin{codeblock}
1765+
// The following concept ensures a specialization of \tcode{A} is deduced.
1766+
template <class> class AA;
1767+
template <class V> class AA<A<V>> { };
1768+
template <class T> concept deduces_A = requires { sizeof(AA<T>); };
1769+
1770+
// \tcode{f1} is formed from the constructor \#1 of \tcode{C}, generating the following function template
1771+
template<T, U>
1772+
auto f1(T, U) -> C<T, U>;
1773+
1774+
// Deducing arguments for \tcode{C<T, U>} from \tcode{C<V *, V*>} deduces \tcode{T} as \tcode{V *} and \tcode{U} as \tcode{V *};
1775+
// \tcode{f1'} is obtained by transforming \tcode{f1} as described by the above procedure.
1776+
template<class V> requires deduces_A<C<V *, V *>>
1777+
auto f1_prime(V *, V*) -> C<V *, V *>;
1778+
1779+
// \tcode{f2} is formed the deduction-guide \#2 of \tcode{C}
1780+
template<class T, class U> auto f2(T, U) -> C<T, std::type_identity_t<U>>;
1781+
1782+
// Deducing arguments for \tcode{C<T, std::type_identity_t<U>>} from \tcode{C<V *, V*>} deduces \tcode{T} as \tcode{V *};
1783+
// \tcode{f2'} is obtained by transforming \tcode{f2} as described by the above procedure.
1784+
template<class V, class U>
1785+
requires deduces_A<C<V *, std::type_identity_t<U>>>
1786+
auto f2_prime(V *, U) -> C<V *, std::type_identity_t<U>>;
1787+
1788+
// The following concept ensures a specialization of \tcode{B} is deduced.
1789+
template <class> class BB;
1790+
template <class V> class BB<B<V>> { };
1791+
template <class T> concept deduces_B = requires { sizeof(BB<T>); };
1792+
1793+
// The guides for \tcode{B} derived from the above \tcode{f1'} and \tcode{f2'} for \tcode{A} are as follows:
1794+
template<std::Integral W>
1795+
requires deduces_A<C<W *, W *>> && deduces_B<C<W *, W *>>
1796+
auto f1_prime_for_B(W *, W *) -> C<W *, W *>;
1797+
1798+
template<std::Integral W, class U>
1799+
requires deduces_A<C<W *, std::type_identity_t<U>>> &&
1800+
deduces_B<C<W *, std::type_identity_t<U>>>
1801+
auto f2_prime_for_B(W *, U) -> C<W *, std::type_identity_t<U>>;
1802+
\end{codeblock}
16641803
\end{example}%
16651804
\indextext{overloading!argument lists|)}%
16661805
\indextext{overloading!candidate functions|)}

source/preprocessor.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,7 @@
16891689
\defnxname{cpp_coroutines} & \tcode{201902L} \\ \rowsep
16901690
\defnxname{cpp_decltype} & \tcode{200707L} \\ \rowsep
16911691
\defnxname{cpp_decltype_auto} & \tcode{201304L} \\ \rowsep
1692-
\defnxname{cpp_deduction_guides} & \tcode{201703L} \\ \rowsep
1692+
\defnxname{cpp_deduction_guides} & \tcode{201907L} \\ \rowsep
16931693
\defnxname{cpp_delegating_constructors} & \tcode{200604L} \\ \rowsep
16941694
\defnxname{cpp_enumerator_attributes} & \tcode{201411L} \\ \rowsep
16951695
\defnxname{cpp_fold_expressions} & \tcode{201603L} \\ \rowsep

source/templates.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3831,7 +3831,7 @@
38313831
\pnum
38323832
A \grammarterm{template-declaration} in which the \grammarterm{declaration} is an
38333833
\grammarterm{alias-declaration}\iref{dcl.dcl} declares the
3834-
\grammarterm{identifier} to be an \defn{alias template}.
3834+
\grammarterm{identifier} to be an \defnadj{alias}{template}.
38353835
An alias template is a name for a family of
38363836
types. The name of the alias template is a \grammarterm{template-name}.
38373837

0 commit comments

Comments
 (0)