std::unique_ptr<std::istream>持有std::ifstream指针编译报错,如何解决?
问题解决:Clang下
unique_ptr<基类>无法接收unique_ptr<派生类>的赋值 你遇到的问题源于std::unique_ptr<std::ifstream>和std::unique_ptr<std::istream>的deleter类型不匹配——前者的deleter是std::default_delete<std::ifstream>,后者是std::default_delete<std::istream>。Clang严格遵循C++标准,不允许这种隐式转换;而MSVC做了非标准扩展才支持该赋值操作。
以下是几种可行的解决方法:
方法一:显式转换为基类unique_ptr
将make_unique返回的派生类unique_ptr直接转换为基类类型,利用unique_ptr的移动构造完成赋值:
std::unique_ptr<std::istream> stream; stream = std::unique_ptr<std::istream>(std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary));
方法二:用reset()转移所有权
调用reset()方法,传入派生类unique_ptr释放的原始指针,直接完成所有权转移:
std::unique_ptr<std::istream> stream; stream.reset(std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary).release());
方法三:显式指定统一deleter类型(可选)
可以显式声明基类的deleter类型(实际默认就是该类型,此写法仅为明确语义):
std::unique_ptr<std::istream, std::default_delete<std::istream>> stream; stream = std::unique_ptr<std::istream>(std::make_unique<std::ifstream>(path, std::ios::in | std::ios::binary));
注意事项
std::istream的析构函数是虚函数,因此用基类的default_delete销毁派生类std::ifstream对象是完全安全的,不会引发内存泄漏或未定义行为。
内容的提问来源于stack exchange,提问作者Kaiyakha
相关产品推荐
相关产品推荐

