Using std::make_unique with a custom deleter
The whole point of make_unique
is to encapsulate the notion of "use new
to create a T
from given constructor arguments and use delete
to destroy it".
If you wanted a custom deleter, you would also have to specify how to create the object, and then there would be nothing more gained from having the emplacing maker function.
I wrote some examples of custom maker functions for certain unique resource handles in this post.
Unique_ptr with custom deleter
You cannot use std::make_unique
with a custom deleter. You’ll need to use the regular constructor instead:
auto unique = std::unique_ptr<A, Deleter>(new A(5), Deleter());
Of course this will still require you to fix the rest of your code: make the constructor of A
public, and declare A
before Deleter
. And you’d need to replace new A(…)
by the proper construction that matches the custom Deleter
.
And it’s worth noting that this might leak memory if the Deleter
constructor throws, so you need to make sure that it doesn’t do that.
Using std::make_unique with custom deleter on a derived class?
This is (one of) the signature(s) of make_unique
, the one that I guess you expect to be used:
template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args );
Where T
is the type of the object you want to create, Args...
are the types of the arguments you are to forward to the constructor.
As you can see, you cannot indicate a custom deleter with the make_*
helper functions for smart pointers (neither with make_unique
, nor with make_shared
).
You have to explicitly construct your pointer as it follows:
std::unique_ptr<T, D> ptr{new T{)};
If the deleter is not default constructible, you can do this:
std::unique_ptr<T, D> ptr{new T{}, d};
Where d
is an instance of the deleter.
How to use a custom deleter using WinAPI with std::make_unique?
make_unique
returns unique_ptr
with defaulted deleter.
To provide your custom version you have to call unique_ptr(Pointer,Deleter)
version of unique_ptr
ctor:
template <typename Function>
class PtrDeleter {
Function _Closer;
public:
void operator()(void* memBlock) const {
_Closer(memBlock);
}
};
int main() {
PtrDeleter<decltype(&CloseHandle)> deleter;
void* openThread = OpenThread(0,false,0);
std::unique_ptr<void, decltype(deleter)> ptr(openThread,deleter);
}
Demo
How do I use a custom deleter with a std::unique_ptr member?
Assuming that create
and destroy
are free functions (which seems to be the case from the OP's code snippet) with the following signatures:
Bar* create();
void destroy(Bar*);
You can write your class Foo
like this
class Foo {
std::unique_ptr<Bar, void(*)(Bar*)> ptr_;
// ...
public:
Foo() : ptr_(create(), destroy) { /* ... */ }
// ...
};
Notice that you don't need to write any lambda or custom deleter here because destroy
is already a deleter.
using custom deleter with unique_ptr
Should be
unique_ptr<FILE, int(*)(FILE*)>(fopen("file.txt", "rt"), &fclose);
since http://en.cppreference.com/w/cpp/memory/unique_ptr
or, since you use C++11, you can use decltype
std::unique_ptr<FILE, decltype(&fclose)>
primr 5 edition. unique_ptr constructor from custom deleter function
std::unique_ptr
doesn't have a constructor that only takes a custom deleter. You'd have to pass nullptr
as the pointer value if you want a null pointer with a custom deleter.
On your second point, that is correct. They didn't add make_unique until c++14, for really no other reason than that C++11 was a huge revision and some features didn't make it in.
Can I succintly declare std::unique_ptr with custom deleter?
Let the language do the hard work!
#include <memory>
struct qdr_link_t;
qdr_link_t* new_qdr_link_t();
void free_qdr_link_t(qdr_link_t*);
template <typename T, typename Deleter>
auto make_unique_ptr(T* raw, Deleter deleter)
{
return std::unique_ptr<T, Deleter>(raw, deleter);
}
//std::unique_ptr<qdr_link_t, decltype(&free_qdr_link_t)> link{new_qdr_link_t(), free_qdr_link_t};
auto link = make_unique_ptr(new_qdr_link_t(), free_qdr_link_t);
Add std::forward
to taste (if you care).
For C++11, you'll need to add the trailing return type -> std::unique_ptr<T, Deleter>
to make_unique_ptr
, or just put that in the "normal" return type.
Related Topics
C++ Array Size Dependent on Function Parameter Causes Compile Errors
How to Write Make_Unique() in VS2012
How to Determine Sizeof Class with Virtual Functions
G++' Is Not Recognized as an Internal or External Command, Operable Program or Batch File
Equivalent of Console.Readline() in C++
Why Add Void to Method Parameter List
Sorting a List of a Custom Type
Concatenate Char Arrays in C++
Is the Comma in a Variable List a Sequence Point
Random Number Generator - Why Seed Every Time
Check If a Type Is Passed in Variadic Template Parameter Pack
Stl Algorithms: Why No Additional Interface for Containers (Additional to Iterator Pairs)
Extra Leading Zeros When Printing Float Using Printf
Is There an Non-Short Circuited Logical "And" in C++
Can Pointers Be of Different Sizes
Boost.Python Call by Reference:Typeerror: No To_Python (By-Value) Converter Found for C++ Type: