VS2015中unique_ptr的lambda删除器编译报错问题求助
解决VS2015中带Lambda删除器的
unique_ptr赋值报错问题 这个问题我在从旧版VS升级到VS2015的时候也踩过坑,核心原因其实和Lambda的特性以及C++标准对unique_ptr的要求直接相关。
先拆解下你的代码问题:你用Lambda作为unique_ptr的自定义删除器,并用decltype(cpcdeleter)指定删除器类型。但Lambda生成的闭包类型默认没有可访问的赋值运算符(C标准明确规定闭包类型的赋值运算符被删除)。而unique_ptr的赋值操作需要能够复制或移动它的删除器,当删除器类型不支持赋值时,编译器就会抛出“赋值运算符已被删除”的错误。VS2012可能因为非标准扩展绕过了这个检查,但VS2015更严格遵循C标准,所以报错了。
下面给你几个可行的解决方案:
方案1:改用函数指针作为删除器类型
把Lambda换成普通函数,用函数指针定义unique_ptr的删除器类型,函数指针天然支持赋值:
// 先定义删除器函数 void CpcDeleter(CP_CONVERT* ptr) { KillCpConvert(&ptr); } // 声明unique_ptr时指定函数指针类型 std::unique_ptr<CP_CONVERT, void(*)(CP_CONVERT*)> cpc; // 赋值操作可正常执行 cpc = std::unique_ptr<CP_CONVERT, void(*)(CP_CONVERT*)>(CreateCpConvert(), CpcDeleter);
方案2:用std::function包装删除器
如果想保留Lambda的灵活性,可以用std::function包装删除器,std::function本身支持赋值操作:
#include <functional> // 声明时用std::function作为删除器类型 std::unique_ptr<CP_CONVERT, std::function<void(CP_CONVERT*)>> cpc; auto cpcdeleter = [](CP_CONVERT* ptr) { KillCpConvert(&ptr); }; // 赋值时直接传入Lambda,std::function会自动包装 cpc = std::unique_ptr<CP_CONVERT, std::function<void(CP_CONVERT*)>>(CreateCpConvert(), cpcdeleter);
这个方案会有一点点运行时性能开销,但在绝大多数业务场景下完全可以忽略。
方案3:直接初始化,避免赋值操作
如果代码逻辑允许,最推荐的方式是直接初始化unique_ptr,跳过默认构造+赋值的步骤,从根源上避免触发删除器的赋值操作:
auto cpcdeleter = [](CP_CONVERT* ptr) { KillCpConvert(&ptr); }; // 直接创建并初始化unique_ptr,无需后续赋值 std::unique_ptr<CP_CONVERT, decltype(cpcdeleter)> cpc(CreateCpConvert(), cpcdeleter);
这个方案没有任何额外开销,也是最符合C++标准的写法。
内容的提问来源于stack exchange,提问作者Richard Matheson
相关产品推荐
相关产品推荐

