|
6350 | 6350 | searching for it in the global scope. |
6351 | 6351 |
|
6352 | 6352 | \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 |
6365 | 6354 | function lookup is used to find the matching deallocation |
6366 | 6355 | function\iref{expr.delete}. |
| 6356 | +For a placement allocation function, the selection process is described below. |
6367 | 6357 | In any case, |
6368 | 6358 | the matching deallocation function (if any) shall be non-deleted and |
6369 | 6359 | 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 |
6370 | 6392 | \begin{example} |
6371 | 6393 | \begin{codeblock} |
6372 | 6394 | struct S { |
|
6380 | 6402 | S* p = new (0) S; // error: non-placement deallocation function matches |
6381 | 6403 | // placement allocation function |
6382 | 6404 | \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 |
6383 | 6416 |
|
| 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} |
6384 | 6454 | \end{example} |
6385 | 6455 |
|
6386 | 6456 | \pnum |
|
0 commit comments