为啥 unique_ptr<T> 不能从 T* 构造?
Posted
技术标签:
【中文标题】为啥 unique_ptr<T> 不能从 T* 构造?【英文标题】:Why is unique_ptr<T> not constructible from T*?为什么 unique_ptr<T> 不能从 T* 构造? 【发布时间】:2021-02-25 16:28:05 【问题描述】:这个代码有什么“错误”,举个简单的例子?
unique_ptr<char> meow = strdup("meow");
无论我是否为unique_ptr
模板提供“删除器”参数,都无法从T*
分配unique_ptr<T>
。
<memory>
为什么不提供这个看似直观的快捷方式?这仅仅是一种疏忽,还是出于某种原因,这种可分配性从根本上来说是个坏主意?
【问题讨论】:
应该是:std::unique_ptr<char[]> meowstrdup("meow");
这能回答你的问题吗? unique_ptr operator=
“为什么 =
的潜在错误用法?甚至auto_ptr
也从未提供过。
请注意,即使meow = strdup()
可以工作,您也必须使用调用free()
的自定义删除器,而不是调用delete
。
【参考方案1】:
<memory>
为什么不提供这个看似直观的快捷方式?
想象一下你有
int bar;
int * foo = &bar;
std::unique_ptr<int> uptr = foo;
// use uptr
当uptr
超出范围时,它会尝试执行delete pointer;
,这将尝试在new
未分配的内存上调用delete
。这是未定义的行为,可能会导致各种问题。标准不允许编写这样的错误代码,而不是允许它。
如果您确实确定要从现有指针构造unique_ptr
,并且您知道默认删除器就是您想要的,那么您可以使用以下形式
auto pointer_name = std::unique_ptr<type>(pointer_i_know_needs_to_be_deleted);
【讨论】:
@NicolBolas IIRC,std::unique_ptr
不会关闭 CTAD,因为您无法区分 unique_ptr(new int);
和 unique_ptr(new int[10]);
我可以想象 很多 其他程序员错误 - 包括显式释放之前给 unique_ptr
的指针。您提出的构造有效,但是,该死的,它不能转换为T*
——甚至不能转换为const T*
@MikhailT。 - 是的,它可以。你打电话给get()
,你会得到一个T*
。
@MikhailT。 它不能转换成T*
——甚至不能转换成const T*
是什么意思?您是在谈论将unique_ptr
传递给采用原始指针的函数吗?如果是这样,那么您需要使用 get
从中获取原始指针。指针很难正确。与原始指针不同,unique_ptr
旨在尝试限制您可以使用它做的错误。
@MikhailT。随着时间的推移,隐式转换被认为比让程序员输入更多的字母更危险(修复错误的时间)。转换运算符可能会参与意外转换,从而导致难以诊断错误。要跟进,您可以研究为什么(例如)std::string
具有 c_str()
而不是隐式转换运算符。以上是关于为啥 unique_ptr<T> 不能从 T* 构造?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能将 new 创建的 &client 对象分配给 unique_ptr
unique_ptr<T> 和 unique_ptr<T>&& 之间的区别 [重复]
为啥我不能在 C++14 的 lambda 中移动 std::unique_ptr?
将所有权从 unique_ptr<T,void(*)(T*)> 转移到 unique_ptr<const T,void(*)(const T*)>