-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathp2582.tex
154 lines (112 loc) · 5.57 KB
/
p2582.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
\input{wg21common}
\newcommand{\forceindent}{\parindent=1em\indent\parindent=0pt\relax} % For indenting a paragraph containing code that can't be laid out as a {codeblock} because it also contains \emph
\pretolerance=10000 % prevent overfull lines
\begin{document}
\title{Wording for class template argument deduction from inherited constructors}
\author{
Timur Doumler \small(\href{mailto:[email protected]}{[email protected]})
}
\date{}
\maketitle
\begin{tabular}{ll}
Document \#: & P2582R1 \\
Date: & 2022-05-20\\
Project: & Programming Language C++ \\
Audience: & Core Working Group
\end{tabular}
\begin{abstract}
This paper provides wording for class template argument deduction from inherited constructors. See \cite{P1021R6} for rationale.
\end{abstract}
\vspace{5mm}
\section{Proposed wording}
The proposed changes are relative to the C++ working draft \cite{N4910}.
In [over.match.class.deduct], append to paragraph 1 as follows:
\begin{adjustwidth}{0.5cm}{0.5cm}
except that additional parameter packs of the form $\tcode{P}_j \tcode{...}$
are inserted into the parameter list in their original aggregate element position corresponding to each non-trailing aggregate element of type $\tcode{P}_j$
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 $\tcode{T}_n \tcode{...}$.
\added{In addition, if \tcode{C} is defined and inherits constructors ([namespace.udecl]) from a direct base class denoted in the \emph{base-specifier-list} by a \emph{class-or-decltype} \tcode{B}, let \tcode{A} be an alias template whose template parameter list is that of \tcode{C} and whose \emph{defining-type-id} is \tcode{B}. If \tcode{A} is a deducible template ([dcl.type.simple]), the set contains the guides of \tcode{A} with the return type \tcode{R} of each guide replaced with \tcode{typename CC<R>::type} given a class template}
\added{\tcode{ template <typename> class CC;}}
\added{whose primary template is not defined and with a single partial specialization whose template parameter list is that of \tcode{A} and whose template argument list is a specialization of \tcode{A} with the template argument list of \tcode{A} ([temp.dep.type]) having a member typedef \tcode{type} designating a template specialization with the template argument list of \tcode{A} but with \tcode{C} as the template.}
\begin{addedblock}
\begin{note}
\added{Equivalently, the template parameter list of the specialization is that of \tcode{C}, the template argument list of the specialization is \tcode{B}, and the member typedef names \tcode{C} with the template argument list of \tcode{C}.}
\end{note}
\end{addedblock}
\end{adjustwidth}
\pagebreak
In [over.match.class.deduct], add the following example:
\begin{adjustwidth}{0.5cm}{0.5cm}
\begin{addedblock}
\begin{example}
\begin{codeblock}
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 \tcode{C<int>}
D d(42); // Error: deduction failed, no inherited deduction guides
B(int) -> B<char>;
C c2(42); // OK, deduces \tcode{C<char>}
template <typename T> struct E : public B<int> {
using B<int>::B;
};
E e(42); // Error: deduction failed, arguments of \tcode{E} cannot be deduced from guides introduced
template <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 \tcode{G<char, bool>}
\end{codeblock}
\end{example}
\end{addedblock}
\end{adjustwidth}
In [over.match.best.general], insert as follows:
\begin{adjustwidth}{0cm}{0.5cm}
\begin{itemize}
\item
\tcode{F1} and \tcode{F2} are rewritten candidates, and
\tcode{F2} is a synthesized candidate
with reversed order of parameters
and \tcode{F1} is not
\begin{example}
\begin{codeblock}
struct S {
friend std::weak_ordering operator<=>(const S&, int); // \#1
friend std::weak_ordering operator<=>(int, const S&); // \#2
};
bool b = 1 < S(); // calls \#2
\end{codeblock}
\end{example}
or, if not that,
\item \added{\tcode{F1} and \tcode{F2} are generated from class template argument deduction ([over.match.class.deduct]) for a class \tcode{D}, and \tcode{F2} is generated from inheriting constructors from a base class of \tcode{D} while \tcode{F1} is not, and for each explicit function argument, the corresponding parameters of \tcode{F1} and \tcode{F2} are either both ellipses or have the same type, or, if not that,}
\item
\tcode{F1} is generated from a
\emph{deduction-guide} ([over.match.class.deduct])
and \tcode{F2} is not, or, if not that,
\end{itemize}
\end{adjustwidth}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Known issues}
The mechanism for class template argument deduction from inherited constructors proposed here relies on the existing mechanism for class template argument deduction from alias templates. Core issue \cite{CWG2467} should be expanded to include additional instances of the problem introduced by this paper.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Document history}
\begin{itemize}
\item \textbf{R0}, 2022-05-15: Initial version.
\item \textbf{R1}, 2022-05-20: Wording changes following CWG review.
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section*{Acknowledgements}
Many thanks to Hubert Tong for his help with fixing the wording.
\renewcommand{\bibname}{References}
\bibliographystyle{abstract}
\bibliography{ref}
\end{document}