I want to do automatic cleanup using std::unique_ptr but to initialize the unique_ptr I need an address to point to. How can I avoid the noUse variable?
bool noUse;
auto deleter = [](bool *){ DESTROY_SOMETHING };
std::unique_ptr<bool, decltype(deleter)> upp(&noUse, deleter); // I want to avoid the usage of this extra noUse variable
START_SOMETHING
//COMPLEX IF ELSE RETURN LOGIC
**UPDATE: ** I finally resorted to this code. Thanks everyone for quick responses.
auto deleter = [](void *){ DESTROY_SOMETHING };
std::unique_ptr<void, decltype(deleter)> upp(nullptr, deleter);
if(enabled)
{
//START_SOMETHING
upp.reset(reinterpret_cast<void *>&upp);
}
//COMPLEX IF ELSE RETURN LOGIC
As long as the custom deleter doesn't require noUse
to have any specific value, you can use some arbitrary integer literal (other than zero, that would make it a null pointer):
auto deleter = [](bool *){ DESTROY_SOMETHING };
// slightly longer but more robust: reinterpret_cast<bool*>(&upp)
std::unique_ptr<bool, decltype(deleter)> upp(reinterpret_cast<bool*>(1), deleter);
// ...
This is a bit of a hack, and there are better solutions, such as std::experimental::scope_exit
. It also doesn't make much sense that this is using a bool*
, why not just a void*
if we don't care about the type?
You can also build your own solution, see:
@Joe has written a solution very similar to std::experimental::scope_exit
which does this.
Note 1: conversion of 1
to bool*
has implementation-defined effect ([expr.reinterpret_cast]), using this pointer is implementation-defined ([basic.stc.general]), and comparison of the pointer to nullptr
is implementation-defined, though never UB ([expr.eq]).
Note 2: Developers commonly create a local static
variable and take its address when they need a std::unique_ptr
as a "scope exit object". This is the most robust option.