A std::nothrow_t
функция освобождения существует, но вы не можете вызвать ее с выражением delete
.
Функция освобождения существует для полноты. Если выражение new
завершается неудачно из-за исключения, компилятору необходимо освободить память, выделенную ему через operator new
, с соответствующим вызовом operator delete
. Таким образом, должен быть operator delete
, который принимает std::nothrow_t
, чтобы разрешить это.
(То есть, как правило, выражение new
с формой new (args...) T
выделит память при вызове operator new(sizeof(T), args...)
. «Сопоставить» означает вызвать operator delete
с теми же аргументами, кроме первого .)
Обратите внимание, что вы можете позвонить оператору напрямую: operator delete(memory, std::nothrow);
. Однако выражение delete
никогда не вызывает глобальную функцию освобождения с дополнительными параметрами.
Так что вы можете «позвонить» с помощью:
struct always_throw
{
always_throw() { throw std::exception(); }
};
new (std::nothrow) always_throw;
В какой-то момент это выделит память при вызове:
void* __memory = operator new(sizeof(always_throw), std::nothrow);
Поскольку инициализация объекта вызывает, компилятору необходимо освободить выделенную память с помощью соответствующей функции освобождения, поэтому он делает:
operator delete(__memory, std::nothrow);
Вызов std::nothrow_t
версии.