A std::nothrow_t
deallocation function exists, but you cannot call it with a delete
expression.
The deallocation function is there for completeness. If a new
expression fails because of an exception, the compiler needs to free the memory it allocated via operator new
with a matching call to operator delete
. So there needs to be an operator delete
that accepts a std::nothrow_t
, to allow this.
(That is, in general, a new
expression with the form new (args...) T
will allocate memory with a call to operator new(sizeof(T), args...)
. To "match" means to call operator delete
with the same arguments, except the first.)
Note you can call the operator directly: operator delete(memory, std::nothrow);
. However, a delete
expression never calls a global deallocation function with additional parameters.
So you can "call" it with:
struct always_throw
{
always_throw() { throw std::exception(); }
};
new (std::nothrow) always_throw;
At some point, this will allocate memory with a call to:
void* __memory = operator new(sizeof(always_throw), std::nothrow);
Since the initialization of the object throws, the compiler needs to free the allocated memory with a matching deallocation function, so it does:
operator delete(__memory, std::nothrow);
Calling the std::nothrow_t
version.