This is not a duplicate of questions on template constructors or even on calling inherited template constructors.
It is specifically about calling the inherited constructor in a subclass of an class instance(?) of the unique_ptr<...,...> template.
The problem
To make the code easier to understand, I'm using using
in this example:
using B = std::unique_ptr<int *, decltype(&::free)>;
class int_ptr : public B {
int_ptr(int *b) : B(b, &::free) { };
};
but compilation fails:
In constructor 'int_ptr::int_ptr(int*)':
error: no matching function for call to
'std::unique_ptr<int*, void (*)(void*) throw ()>::unique_ptr(int*&, void (*)(void*) throw ())'
int_ptr(int *b) : B(b, &::free) { };
^
The only possible cause of lack of function matching I can think of is the presence of throw ()
but I'm not sure what to do about that, or if it even is a problem. Possibly unique_ptr
is no-throw.
Otherwise the no-matching function is precisely what I would expect to have matched.
The reason
I don't want to keep specifying the destructor every time I declare an instance of a unique_ptr. There is a good alternative in this answer https://stackoverflow.com/a/16615285/2332068, but I'm interested to know what is wrong with my attempt.
Of course, in real life it is not an int*
I'm trying to wrap in unique_ptr
, but some opaque (but not void*
) pointer.
My intent is to have all these pointers from a C API correctly freed when the scope exits.
Perhaps I could constrain these pointers into a class/struct with a destructor but I can't see that it would save much.
Result
With the tip from @RSahu, I have come up with this, unique_dptr
to avoid the need to keep specifying the destructor, but as an alternative to overriding the template delete function in the std namespace:
void free_int(int* p) {
delete p;
}
template<typename T, void (*D)(T*)>
class unique_dptr : public std::unique_ptr<T, decltype(D)> {
public: unique_dptr(T* t) : std::unique_ptr<T, decltype(D)>(t, D) { };
};
using int_ptr = unique_dptr<int, ::free_int>;
int_ptr i(new int(2));