如何在构造函数中使用删除器初始化 std::unique_ptr?
Posted
技术标签:
【中文标题】如何在构造函数中使用删除器初始化 std::unique_ptr?【英文标题】:How do I initialize a std::unique_ptr with a deleter in a constructor? 【发布时间】:2021-02-05 01:46:12 【问题描述】:我正在尝试将 C 库原始指针包装在 std::unique_ptr 中,并使用带有 Deleter 的构造函数来调用库释放函数。为了设置原始指针,我必须在构造函数中进行一些设置,因此我无法在初始化列表中构造 unique_ptr。
.h
class Resampler
public:
Resampler(unsigned int baseSamplerate, unsigned int channels);
private:
std::unique_ptr<SwrContext, decltype(&swr_free)> contextnullptr, 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);
这不会在 IDE 中产生错误,但编译器会报错:
> 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 ;
和
std::unique_ptr<SwrContext, decltype(&swr_free)> context;
不是有效的构造函数,并且
std::unique_ptr<SwrContext, decltype(&swr_free)> context;
生产
错误:'Resampler' 的构造函数必须显式初始化 没有默认构造函数的成员“上下文”
那么有没有办法做到这一点,还是我应该将上下文设为原始指针并手动管理?
【问题讨论】:
【参考方案1】:std::unique_ptr<T>
的删除器在这种情况下必须是可调用对象。尝试像这样使用 仿函数:
struct swr_deleter
void operator()(SwrContext* context)
if (context != nullptr)
swr_free(context);
那么您的std::unique_ptr
将如下所示:
std::unique_ptr<SwrContext, swr_deleter> context;
【讨论】:
这让我可以让它工作。我认为问题是因为 sw_free 需要 ** 而不是 *。所以在我的情况下,我需要做 `swr_free(&context);'。我认为这可能是我原来的方式行不通。 "std::unique_ptr<T>
的删除器必须是可调用对象" - 独立函数也可用作删除器。只是不是在这种特殊情况下,因为swr_free()
的签名与删除器的要求不兼容,因为它需要SwrContext**
而不是SwrContext*
。使用仿函数可以解决这个问题以上是关于如何在构造函数中使用删除器初始化 std::unique_ptr?的主要内容,如果未能解决你的问题,请参考以下文章