ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-无法将带有NULL删除器的std :: unique_ptr移动到std :: shared_ptr?

2019-10-11 14:08:16  阅读:229  来源: 互联网

标签:c move c14 unique-ptr


我想将NULL std :: unique_ptr移至std :: shared_ptr,如下所示:

std::unique_ptr<float> test = nullptr;
std::shared_ptr<float> test2 = std::move(test);

据我所知,这样做是合法的,并且在Visual Studio 2015和GCC中运行良好.

但是,我不能对具有删除器声明的std :: unique_ptr进行相同操作,如下所示:

std::unique_ptr<float,void(*)(float*)> test = nullptr;
std::shared_ptr<float> test2 = std::move(test);

上面的代码将无法在Visual Studio中编译,并且将触发静态断言失败“错误C2338:使用空删除器指针构造的unique_ptr”.

我可以改用std :: function删除器,在这种情况下,可以避免静态断言失败:

std::unique_ptr<float,std::function<void(float*)>> test = nullptr;
std::shared_ptr<float> test2 = std::move(test);

在这种情况下,代码可以正常编译,但是一旦销毁了test2的最后一个std :: shared_ptr副本,我就会中止运行.

为什么后两种情况如此成问题?

奇怪的是,如果我将test2的类型从std :: shared_ptr更改为std :: unique_ptr,第二种情况仍然会触发静态断言失败,但是情况1和情况3都可以正常工作:

{
    std::unique_ptr<float> test = nullptr;
    std::unique_ptr<float> test2 = std::move(test); // Works fine
}
{
    //std::unique_ptr<float,void(*)(float*)> test = nullptr; // triggers a static assert failure
    //std::unique_ptr<float,void(*)(float*)> test2 = std::move(test);
}
{
    std::unique_ptr<float,std::function<void(float*)>> test = nullptr;
    std::unique_ptr<float,std::function<void(float*)>> test2 = std::move(test); // Works fine
}

解决方法:

如果删除程序类型是指针,则您尝试使用的unique_ptr构造函数(默认构成删除程序)的格式不正确(在C 17之前),或者被SFINAE禁用(从C 17开始),如果该删除程序类型是指针,则可以防止意外创建一个unique_ptr,其删除器本身就是一个空指针.如果您确实想创建这样的unique_ptr,则可以通过显式传递一个null删除器来实现:

std::unique_ptr<float,void(*)(float*)> test(nullptr, nullptr);

这个unique_ptr对象不是很有用,因为它无法删除任何内容.

通过使用空的std :: function删除器,您已经告诉编译器“是的,我真的很想自杀.”当然,当最后一个std :: shared_ptr被销毁时,将调用空std :: function,并且会发生未定义的行为.您还期望什么?

标签:c,move,c14,unique-ptr
来源: https://codeday.me/bug/20191011/1893012.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有