You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带自定义删除器的std::unique_ptr如何通过std::make_unique调用类构造函数?

问题分析与解决方案

首先得明确:std::make_unique天生不支持直接搭配自定义删除器使用,这就是你报错的根源。

为什么会报错?

你写的std::make_unique<A, Deleter>(5),编译器会把模板参数里的Deleter理解为「A的构造函数需要接收的参数类型」,而不是unique_ptr的删除器类型。所以它期望你传入一个Deleter对象,但你传了int类型的5,自然就触发了类型转换错误。

标准库的make_unique设计初衷是简化使用默认删除器的unique_ptr创建流程,它的模板参数只用来指定要创建的对象类型,以及构造函数的参数类型,根本没有预留指定自定义删除器的位置。

正确的实现方式

方式一:手动构造unique_ptr

直接跳过make_unique,用unique_ptr的构造函数来创建,同时传入动态分配的对象和自定义删除器实例:

#include <memory>
struct Deleter {
    void operator() (A* a) {}
};
class A {
    A(int a) {}
    friend int main(); // 必须让main能访问私有构造函数,否则new A(5)会报错
};
int main() {
    std::unique_ptr<A, Deleter> unique(new A(5), Deleter());
}

方式二:封装自己的「带删除器的make_unique」

如果你习惯用类似make_unique的简洁语法,可以自己封装一个模板函数:

#include <memory>
#include <utility> // 用于std::forward

struct Deleter {
    void operator() (A* a) {}
};
class A {
    A(int a) {}
    // 友元自定义函数,让它能访问私有构造函数
    template<typename T, typename Del, typename... Args>
    friend std::unique_ptr<T, Del> make_unique_with_deleter(Args&&... args);
};

template<typename T, typename Deleter, typename... Args>
std::unique_ptr<T, Deleter> make_unique_with_deleter(Args&&... args) {
    // 完美转发构造函数参数,同时创建带自定义删除器的unique_ptr
    return std::unique_ptr<T, Deleter>(new T(std::forward<Args>(args)...), Deleter());
}

int main() {
    auto unique = make_unique_with_deleter<A, Deleter>(5);
}

额外注意点

你的代码里A的构造函数是私有成员,不管用哪种方式,都需要让创建对象的代码(main或者自定义的make_unique_with_deleter)拥有访问权限,否则会触发编译错误——上面的示例里已经通过friend声明解决了这个问题。

内容的提问来源于stack exchange,提问作者AathakA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:37:44