Skip to content

Commit 21cb611

Browse files
committed
P3769R1 Clarification of placement new deallocation
1 parent b536020 commit 21cb611

1 file changed

Lines changed: 82 additions & 12 deletions

File tree

source/expressions.tex

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6350,23 +6350,45 @@
63506350
searching for it in the global scope.
63516351

63526352
\pnum
6353-
A declaration of a placement deallocation function matches the
6354-
declaration of a placement allocation function if it has the same number
6355-
of parameters and, after parameter transformations\iref{dcl.fct}, all
6356-
parameter types except the first are identical. If
6357-
the lookup finds a single matching deallocation function, that function
6358-
will be called; otherwise, no deallocation function will be called. If
6359-
the lookup finds a usual deallocation
6360-
function
6361-
and that function,
6362-
considered as a placement deallocation function, would have been
6363-
selected as a match for the allocation function, the program is
6364-
ill-formed. For a non-placement allocation function, the normal deallocation
6353+
For a non-placement allocation function, the normal deallocation
63656354
function lookup is used to find the matching deallocation
63666355
function\iref{expr.delete}.
6356+
For a placement allocation function, the selection process is described below.
63676357
In any case,
63686358
the matching deallocation function (if any) shall be non-deleted and
63696359
accessible from the point where the \grammarterm{new-expression} appears.
6360+
6361+
\pnum
6362+
For a placement allocation function,
6363+
the matching deallocation function is selected as follows:
6364+
\begin{itemize}
6365+
\item
6366+
Each candidate that is a function template is replaced by
6367+
the function template specializations (if any)
6368+
generated using template argument deduction\iref{temp.over,temp.deduct.call}
6369+
with arguments as specified below.
6370+
\item
6371+
Each candidate whose parameter-type-list is not identical to
6372+
that of the allocation function,
6373+
ignoring their respective first parameters,
6374+
is removed from the set of candidates.
6375+
\item
6376+
Each candidate whose associated constraints (if any)
6377+
are not satisfied\iref{temp.constr.constr}
6378+
is removed from the set of candidates.
6379+
\item
6380+
If exactly one function remains, that function is selected.
6381+
\item
6382+
Otherwise, no deallocation function is selected.
6383+
\end{itemize}
6384+
If a usual deallocation function is selected, the program is ill-formed.
6385+
\begin{note}
6386+
A deallocation function with an additional trailing parameter
6387+
compared to the allocation function is never matched,
6388+
even if a default argument is provided.
6389+
\end{note}
6390+
6391+
\pnum
63706392
\begin{example}
63716393
\begin{codeblock}
63726394
struct S {
@@ -6380,7 +6402,55 @@
63806402
S* p = new (0) S; // error: non-placement deallocation function matches
63816403
// placement allocation function
63826404
\end{codeblock}
6405+
\end{example}
6406+
6407+
\begin{example}
6408+
\begin{codeblock}
6409+
struct A {};
6410+
struct T { T(); };
6411+
6412+
void* operator new(std::size_t s, A& al); // \#1
6413+
6414+
template<int = 0>
6415+
void operator delete(void* p, A& al); // \#2
63836416

6417+
A al;
6418+
T* p = new (al) T; // OK, uses \#1 and \#2.
6419+
\end{codeblock}
6420+
\end{example}
6421+
6422+
\begin{example}
6423+
\begin{codeblock}
6424+
template<int I>
6425+
struct A {};
6426+
struct T { T(); };
6427+
6428+
void* operator new(std::size_t s, A<0>& al); // \#1
6429+
6430+
template<int I>
6431+
void operator delete(void* p, A<I>& al);
6432+
void operator delete(void* p, A<0>& al);
6433+
6434+
A<0> al;
6435+
T* p = new (al) T; // OK, uses \#1. No deallocation function is selected (two candidates remain).
6436+
\end{codeblock}
6437+
\end{example}
6438+
6439+
\begin{example}
6440+
\begin{codeblock}
6441+
template<int I>
6442+
struct A {};
6443+
struct T { T(); };
6444+
6445+
void* operator new(std::size_t s, A<0>& al); // \#1
6446+
6447+
template<int I> requires (I > 0)
6448+
void operator delete(void* p, A<I>& al);
6449+
void operator delete(void* p, A<0>& al); // \#2
6450+
6451+
A<0> al;
6452+
T* p = new (al) T; // OK, uses \#1 and \#2.
6453+
\end{codeblock}
63846454
\end{example}
63856455

63866456
\pnum

0 commit comments

Comments
 (0)