Skip to content

Commit eacba78

Browse files
jensmaurerzygoloid
authored andcommitted
P1814R0 Class template argument deduction for alias template
- fixed one f' / f1' vs. f1' / f2' confusion in the example
1 parent d4dc044 commit eacba78

File tree

3 files changed

+142
-6
lines changed

3 files changed

+142
-6
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 deducible template is either a class template or
1390+
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: 131 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,84 @@
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+
whose \grammarterm{defining-type-id}
1577+
is a \grammarterm{simple-template-id} \tcode{B<L>},
1578+
the guides of \tcode{A} are the set of functions or function templates
1579+
formed as follows.
1580+
For each function or function template \tcode{f} in the guides of \tcode{B},
1581+
form a function or function template \tcode{f'}
1582+
according to the following procedure and add it to the set:
1583+
\begin{itemize}
1584+
\item
1585+
Deduce the template arguments of the return type of \tcode{f}
1586+
from \tcode{B<L>} according to the process in \ref{temp.deduct.type}
1587+
with the exception that deduction does not fail
1588+
if not all template arguments are deduced.
1589+
Let \tcode{g} denote the result of substituting
1590+
these deductions into \tcode{f}.
1591+
If the substitution fails, no \tcode{f'} is produced.
1592+
Form the function or function template \tcode{f'} as follows:
1593+
\begin{itemize}
1594+
\item
1595+
The function type of \tcode{f'} is the function type of \tcode{g}.
1596+
\item
1597+
If \tcode{f} is a function template,
1598+
the template parameter list of \tcode{f'} consists of
1599+
all the template parameters of \tcode{A}
1600+
(including their default template arguments)
1601+
that appear in the above deductions or
1602+
(recursively) in their default template arguments,
1603+
followed by the template parameters of \tcode{f} that were not deduced
1604+
(including their default template arguments).
1605+
\item
1606+
The associated constraints\iref{temp.constr.decl} are
1607+
the conjunction of the associated constraints of \tcode{g} and
1608+
a constraint that is satisfied if and only if
1609+
the arguments of \tcode{A} are deducible (see below) from the return type.
1610+
\end{itemize}
1611+
\item
1612+
If \tcode{f} is a copy deduction candidate\iref{over.match.class.deduct},
1613+
then \tcode{f'} is considered to be so as well.
1614+
\item
1615+
If \tcode{f} was generated
1616+
from a deduction-guide\iref{over.match.class.deduct},
1617+
then \tcode{f'} is considered to be so as well.
1618+
\item
1619+
The \grammarterm{explicit-specifier} of \tcode{f'} is
1620+
the \grammarterm{explicit-specifier} of g (if any).
1621+
\end{itemize}
1622+
1623+
\pnum
1624+
The arguments of a template \tcode{A} are said to be
1625+
deducible from a type \tcode{T} if, given a class template
1626+
\begin{codeblock}
1627+
template <typename> class AA;
1628+
\end{codeblock}
1629+
with a single partial specialization
1630+
whose template parameter list is that of \tcode{A} and
1631+
whose template argument list is a specialization of \tcode{A}
1632+
with the template argument list of \tcode{A}\iref{temp.dep.type},
1633+
\tcode{AA<T>} matches the partial specialization.
1634+
15721635
\pnum
15731636
Initialization and overload resolution are performed as described
15741637
in \ref{dcl.init} and \ref{over.match.ctor}, \ref{over.match.copy},
15751638
or \ref{over.match.list} (as appropriate for the type of initialization
15761639
performed) for an object of a hypothetical class type, where
1577-
the selected functions and function templates are considered to be the
1640+
the guides of the template named by the placeholder are considered to be the
15781641
constructors of that class type for the purpose of forming an overload
15791642
set, and the initializer is provided by the context in which class
15801643
template argument deduction was performed.
15811644
As an exception, the first phase in \ref{over.match.list}
15821645
(considering initializer-list constructors)
15831646
is omitted if the initializer list consists of
15841647
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}.
1648+
where \tcode{U} is a specialization of the class template
1649+
for which the placeholder names a specialization or
1650+
a class derived therefrom.
15871651
If the function or function template was generated from
15881652
a constructor or \grammarterm{deduction-guide}
15891653
that had an \grammarterm{explicit-specifier},
@@ -1661,6 +1725,69 @@
16611725

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

0 commit comments

Comments
 (0)