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

如何将无自定义删除器的unique_ptr移动到带自定义删除器的unique_ptr?

问题解决:将无自定义删除器的unique_ptr转换为带自定义删除器的版本

原代码无法编译的核心原因是:std::unique_ptr<TestStruct>和std::unique_ptr<TestStruct, StructDeleter>属于不同的模板实例类型,C++不支持直接在这两种类型间进行移动构造。要完成指针所有权的转移,需要手动提取裸指针并重新构造目标unique_ptr。

可行解决方案

方法1:使用release()转移指针所有权

调用无删除器unique_ptr的release()方法,取出其管理的裸指针(同时原unique_ptr会放弃指针所有权),再用该裸指针构造带自定义删除器的unique_ptr:

#include <memory>
#include <functional>
#include <iostream>

struct TestStruct {
    int a = 100;
};

struct StructDeleter {
    void operator()(TestStruct *ptr) const {
        delete ptr;
    }
};

std::unique_ptr<TestStruct, StructDeleter> MakeNewStruct() {
    std::unique_ptr<TestStruct> st(new TestStruct());

    // 用release()获取裸指针,构造带自定义删除器的unique_ptr
    std::unique_ptr<TestStruct, StructDeleter> customDeleterSt(st.release());
    std::cout << customDeleterSt->a << std::endl;
    return customDeleterSt;
}

int main() {
    auto a = MakeNewStruct();
    std::cout << a->a << std::endl;
    return 0;
}

方法2:直接构造带自定义删除器的unique_ptr(如果允许跳过无删除器步骤)

若无需从外部接口获取无删除器的unique_ptr,可以直接创建目标类型的对象,避免类型转换:

std::unique_ptr<TestStruct, StructDeleter> MakeNewStruct() {
    std::unique_ptr<TestStruct, StructDeleter> customDeleterSt(new TestStruct());
    std::cout << customDeleterSt->a << std::endl;
    return customDeleterSt;
}

关键说明

  • release()是安全的:它会将原unique_ptr内部的指针置为空,确保不会出现双重释放问题。
  • 自定义删除器必须与指针类型匹配:你的StructDeleter的operator()能正确处理TestStruct*,因此可以安全替换默认删除器。如果删除器逻辑更复杂,需确保它能正确接管指针的销毁工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:57:14