Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5683,10 +5683,14 @@
\end{codeblock}
\end{example}

\item Otherwise, if \tcode{T} is a reference type, a prvalue of the type
referenced by \tcode{T} is generated.
\item Otherwise, if \tcode{T} is a reference type, a prvalue is generated.
The prvalue initializes its result object by copy-list-initialization.
The prvalue is then used to direct-initialize the reference.
The type of the temporary is the type referenced by \tcode{T},
unless \tcode{T} is ``reference to array of unknown bound of \tcode{U}'',
in which case the type of the temporary is
the type of \tcode{x} in the declaration \tcode{U x[] $H$},
where $H$ is the initializer list.
\begin{note} As usual, the binding will fail and the program is ill-formed if
the reference type is an lvalue reference to a non-const type. \end{note}

Expand Down
66 changes: 27 additions & 39 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -324,25 +324,6 @@
\tcode{T} is a cv-unqualified non-class, non-array type, the type of
the expression is adjusted to \tcode{T} prior to any further analysis.

\pnum
The \defnadj{cv-combined}{type} of two types \tcode{T1} and \tcode{T2}
is a type \tcode{T3}
similar to \tcode{T1} whose cv-qualification signature\iref{conv.qual} is:
\begin{itemize}
\item
for every $i > 0$, $\cv{}^3_i$ is the union of
$\cv{}^1_i$ and $\cv{}^2_i$;

\item
if the resulting $\cv{}^3_i$ is different from
$\cv{}^1_i$ or $\cv{}^2_i$, then
\tcode{const} is added to every $\cv{}^3_k$ for $0 < k < i$.
\end{itemize}

\begin{note} Given similar types \tcode{T1} and \tcode{T2}, this
construction ensures that
both can be converted to \tcode{T3}. \end{note}

\pnum
\indextext{pointer!composite pointer type}%
The \defn{composite pointer type} of
Expand Down Expand Up @@ -748,34 +729,34 @@
\indextext{type!similar|see{similar types}}%
Two types $\tcode{T}_1$ and $\tcode{T}_2$ are \defnx{similar}{similar types} if
they have cv-decompositions with the same $n$
such that corresponding $P_i$ components are the same
such that corresponding $P_i$ components are either the same
or one is ``array of $N_i$'' and the other is ``array of unknown bound of'',
and the types denoted by \tcode{U} are the same.

\pnum
A prvalue of type $\tcode{T}_1$
can be converted to type $\tcode{T}_2$
if the following conditions are satisfied,
% NB: forbid line break between 'where' and 'cv'
% to stop superscript j from running into
% descender of p on the previous line.
where~$\cv{}_i^j$ denotes the cv-qualifiers in the cv-qualification signature of $\tcode{T}_j$:%
\footnote{These rules ensure that const-safety is preserved by the conversion.}

The \defnadj{cv-combined}{type} of two types \tcode{T1} and \tcode{T2}
is the type \tcode{T3}
similar to \tcode{T1} whose cv-decomposition is such that:
\begin{itemize}
\item $\tcode{T}_1$ and $\tcode{T}_2$ are similar.

\item For every $i > 0$, if \tcode{const} is in $\cv{}_i^1$ then \tcode{const} is in $\cv{}_i^2$, and similarly for \tcode{volatile}.

\item If the $\cv{}_i^1$ and $\cv{}_i^2$ are different,
then \tcode{const} is in every $\cv{}_k^2$ for $0 < k < i$.
\item
for every $i > 0$, $\cv{}^3_i$ is the union of
$\cv{}^1_i$ and $\cv{}^2_i$;
\item
if either $P^1_i$ or $P^2_i$ is ``array of unknown bound of'',
$P^3_i$ is ``array of unknown bound of'', otherwise it is $P^1_i$;
\item
if the resulting $\cv{}^3_i$ is different from $\cv{}^1_i$ or $\cv{}^2_i$,
or the resulting $P^3_i$ is different from $P^1_i$ or $P^2_i$,
then \tcode{const} is added to every $\cv{}^3_k$ for $0 < k < i$.
\end{itemize}

A prvalue of type $\tcode{T}_1$
can be converted to type $\tcode{T}_2$
if the cv-combined type of $\tcode{T}_1$ and $\tcode{T}_2$ is $\tcode{T}_2$.
\begin{note}
If a program could assign a pointer of type \tcode{T**} to a pointer of
type \tcode{const} \tcode{T**} (that is, if line \#1 below were
allowed), a program could inadvertently modify a const object
(as it is done on line \#2). For example,

\begin{codeblock}
int main() {
const char c = 'c';
Expand All @@ -786,6 +767,11 @@
}
\end{codeblock}
\end{note}
\begin{note}
Given similar types \tcode{T1} and \tcode{T2}, this
construction ensures that
both can be converted to the cv-combined type of \tcode{T1} and \tcode{T2}.
\end{note}

\pnum
\begin{note}
Expand Down Expand Up @@ -3997,8 +3983,10 @@
\pnum
For two similar types \tcode{T1} and \tcode{T2}\iref{conv.qual},
a prvalue of type \tcode{T1} may be explicitly
converted to the type \tcode{T2} using a \tcode{const_cast}. The result
of a \tcode{const_cast} refers to the original entity.
converted to the type \tcode{T2} using a \tcode{const_cast}
if, considering the cv-decompositions of both types,
each $P^1_i$ is the same as $P^2_i$ for all $i$.
The result of a \tcode{const_cast} refers to the original entity.
\begin{example}
\begin{codeblock}
typedef int *A[3]; // array of 3 pointer to \tcode{int}
Expand Down
57 changes: 35 additions & 22 deletions source/overloading.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2490,10 +2490,13 @@
\end{example}

\pnum
Otherwise, if the parameter type is ``array of \tcode{N} \tcode{X}'',
if there exists an implicit conversion sequence for each element of the array
from the corresponding element of the initializer list (or from \tcode{\{\}}
if there is no such element), the implicit conversion sequence is
Otherwise, if the parameter type is ``array of \tcode{N} \tcode{X}''
or ``array of unknown bound of \tcode{X}'',
if there exists an implicit conversion sequence
from each element of the initializer list
(and from \tcode{\{\}} in the former case
if \tcode{N} exceeds the number of elements in the initializer list)
to \tcode{X}, the implicit conversion sequence is
the worst such implicit conversion sequence.

\pnum
Expand Down Expand Up @@ -2662,19 +2665,35 @@
\tcode{L2} does not, or, if not that,

\item
\tcode{L1} converts to type ``array of \tcode{N1} \tcode{T}'', \tcode{L2} converts to
type ``array of \tcode{N2} \tcode{T}'', and \tcode{N1} is smaller than \tcode{N2},
\tcode{L1} and \tcode{L2} convert to arrays of the same element type, and
either the number of elements $n_1$ initialized by \tcode{L1}
is less than the number of elements $n_2$ initialized by \tcode{L2}, or
$n_1 = n_2$ and
\tcode{L2} converts to an array of unknown bound and \tcode{L1} does not,
\end{itemize}
even if one of the other rules in this paragraph would otherwise apply.
\begin{example}
\begin{codeblock}
void f1(int); // \#1
void f1(std::initializer_list<long>); // \#2
void g1() { f1({42}); } // chooses \#2
void f1(int); // \#1
void f1(std::initializer_list<long>); // \#2
void g1() { f1({42}); } // chooses \#2

void f2(std::pair<const char*, const char*>); // \#3
void f2(std::initializer_list<std::string>); // \#4
void g2() { f2({"foo","bar"}); } // chooses \#4
void f2(std::pair<const char*, const char*>); // \#3
void f2(std::initializer_list<std::string>); // \#4
void g2() { f2({"foo","bar"}); } // chooses \#4
\end{codeblock}
\end{example}
\begin{example}
\begin{codeblock}
void f(int (&&)[] ); // \#1
void f(double (&&)[] ); // \#2
void f(int (&&)[2]); // \#3

f( {1} ); // Calls \#1: Better than \#2 due to conversion, better than \#3 due to bounds
f( {1.0} ); // Calls \#2: Identity conversion is better than floating-integral conversion
f( {1.0, 2.0} ); // Calls \#2: Identity conversion is better than floating-integral conversion
f( {1, 2} ); // Calls \#3: Converting to array of known bound is better than to unknown bound,
// and an identity conversion is better than floating-integral conversion
\end{codeblock}
\end{example}

Expand Down Expand Up @@ -2758,16 +2777,10 @@
or, if not that,

\item
\tcode{S1}
and
\tcode{S2}
differ only in their qualification conversion and yield similar types
\tcode{T1}
and
\tcode{T2}\iref{conv.qual}, respectively, and the cv-qualification signature of type
\tcode{T1}
is a proper subset of the cv-qualification signature of type
\tcode{T2}
\tcode{S1} and \tcode{S2} differ only
in their qualification conversion\iref{conv.qual} and
yield similar types \tcode{T1} and \tcode{T2}, respectively,
where \tcode{T1} can be converted to \tcode{T2} by a qualification conversion
\begin{example}
\begin{codeblock}
int f(const volatile int *);
Expand Down