带自定义删除器的unique_ptr复制编译报错,请求技术支持
解决带自定义删除器的unique_ptr移动赋值编译错误问题
嘿,我来帮你搞定这个问题!你这段代码里用lambda作为unique_ptr的自定义删除器,在MinGW 5.1.0这个旧版本的编译器下出现了编译错误,其实是因为早期的libstdc对C11标准的unique_ptr支持不够完善导致的。
先看看你的原代码:
#include <iostream> #include<memory> #include <algorithm> using namespace std; auto del = [](int *p) { cout <<"obj deleted "<<endl;delete p;}; int main() { unique_ptr<int, decltype(del)> p1(new int(10), del); unique_ptr<int,decltype(del)> p2; p2 = std::move(p1); }
问题原因
你用decltype(del)获取lambda的类型作为unique_ptr的删除器类型,但lambda的底层类型是没有默认构造函数的。在gcc 5.1.0的旧版标准库实现中,unique_ptr的移动赋值运算符要求删除器类型具备默认构造能力,这就导致了编译失败。
几种可行的解决方案
方案1:改用std::function作为删除器类型
把删除器类型换成std::function<void(int*)>,这样就能避开lambda类型的限制,代码修改后如下:
#include <iostream> #include <memory> #include <functional> using namespace std; int main() { auto del = [](int *p) { cout << "obj deleted " << endl; delete p; }; unique_ptr<int, function<void(int*)>> p1(new int(10), del); unique_ptr<int, function<void(int*)>> p2; p2 = move(p1); }
方案2:升级你的MinGW编译器版本
gcc 5.1.0是比较老的版本了,后续的gcc版本(比如7.x及以上)已经修复了这个标准库实现的问题,升级后你的原代码应该就能正常编译运行。
方案3:自定义一个带默认构造的删除器类
不用lambda,自己写一个删除器结构体,它的类型自带默认构造函数,完美适配旧版标准库:
#include <iostream> #include <memory> using namespace std; struct IntDeleter { void operator()(int* p) const { cout << "obj deleted " << endl; delete p; } }; int main() { unique_ptr<int, IntDeleter> p1(new int(10)); unique_ptr<int, IntDeleter> p2; p2 = move(p1); }
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

