Reputation: 25
I am trying to find a way to write a custom deleter for a C array managed by a unique_ptr in a templated C++ class. I am purposefully trying to make the class leak memory by making the deleter do nothing. In the full class, some constructors allocate the memory and some do not - rather they make use of the memory in a raw byte buffer coming from a data stream.
This is what I tried:
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[]> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(NULL, [](T[]* p){})
{
_array.reset((T*)data);
}
};
The code does not compile, the error message is:
In file included from /tmp/test/test/test.cpp:9:
/tmp/test/test/Matrix.h:22:55: error: expected ')'
, _array(NULL, [](T[]* p){})
^
/tmp/test/test/Matrix.h:22:51: note: to match this '('
, _array(NULL, [](T[]* p){})
^
1 error generated.
Upvotes: 0
Views: 1155
Reputation: 62636
The deleter is a template parameter of std::unique_ptr
. By default it is std::default_delete
, but you can specify something different, e.g.
template <typename T>
struct NonDeleter
{
void operator()(T*) { /* nothing */ }
};
template <typename T>
struct NonDeleter<T[]> : NonDeleter<T> {};
template <class T> class Matrix
{
private:
int _size;
std::unique_ptr<T[], NonDeleter<T[]>> _array;
public:
Matrix(int size, void* data) : _size(size)
, _array(static_cast<T*>(data))
{
}
};
Upvotes: 0
Reputation: 40842
First of all, always create a simple setup to test things:
int main() {
using T = int;
std::unique_ptr<T[]> _array(NULL, [](T[]* p){});
return 0;
}
So now to your problem:
T[]* p
is not valid and should be T* p
.std::default_delete<T>
which is used as default deleter. So you have to write std::unique_ptr<T[],std::function<void(T*)>
. NULL
might be implemented as an integral type, so you should use nullptr
instead, otherwise gcc
won't compile your code (since c++11 you, in general, should use nullptr
instead of NULL
).So putting everything together you get:
int main() {
using T = int;
std::unique_ptr<T[],std::function<void(T[])>> _array(nullptr, [](T* p){});
return 0;
}
Upvotes: 3