Reputation: 9794
I'm trying to wrap a C library raw pointer in a std::unique_ptr and use the constructor with the Deleter to call the library free function. I have to do some setup in the constructor in order to setup the raw pointer so I can't construct the unique_ptr in the initializer list.
.h
class Resampler {
public:
Resampler(unsigned int baseSamplerate, unsigned int channels);
private:
std::unique_ptr<SwrContext, decltype(&swr_free)> context{nullptr, nullptr};
};
.cpp
Resampler::Resampler(unsigned int baseSamplerate, unsigned int channels) : baseSamplerate(baseSamplerate), ratio(1.0), channels(channels) {
int64_t channelLayout;
..
SwrContext *ctx = swr_alloc_set_opts(nullptr,
channelLayout,
AV_SAMPLE_FMT_FLTP,
baseSamplerate,
channelLayout,
AV_SAMPLE_FMT_FLTP,
baseSamplerate,
0,
nullptr);
context = std::unique_ptr<SwrContext, decltype(&swr_free)>(ctx, &swr_free);
setRatio(1.0);
}
This doesn't produce an error in the IDE but the compiler complains:
> error: cannot initialize a parameter of type 'SwrContext **' with an > lvalue of type 'std::__ndk1::unique_ptr<SwrContext, void > (*)(SwrContext **)>::pointer' (aka 'SwrContext *')
std::unique_ptr<SwrContext, decltype(&swr_free)> context{ nullptr };
and
std::unique_ptr<SwrContext, decltype(&swr_free)> context{};
are not valid constructors, and
std::unique_ptr<SwrContext, decltype(&swr_free)> context;
produces
error: constructor for 'Resampler' must explicitly initialize the member 'context' which does not have a default constructor
so is there a way to do this or should I just make context a raw pointer and manually manage?
Upvotes: 1
Views: 812
Reputation: 815
The deleter of a std::unique_ptr<T>
has to be a callable object in this case. Try using a functor like this:
struct swr_deleter
{
void operator()(SwrContext* context)
{
if (context != nullptr)
{
swr_free(context);
}
}
}
Then your std::unique_ptr
will look like this:
std::unique_ptr<SwrContext, swr_deleter> context;
Upvotes: 2