考虑以下程序:
#include <memory>
std::unique_ptr<int> get_it() {
auto p = new int;
return p;
}
int main() {
auto up ( get_it() );
return 0;
}
编译失败,并出现以下错误:
a.cpp:5:9: error: could not convert ‘p’ from ‘int*’ to ‘std::unique_ptr<int>’
return p;
^
为什么这里没有从原始指针到唯一指针的自动转换?那我该做什么呢
动机:我知道使用智能指针来明确所有权应该是一个很好的实践;我从某个地方得到一个指针(我自己的),在这个例子中是一个int*
,我(想我)希望它在一个unique_ptr
中。
如果您正在考虑评论或添加自己的答案,请发送邮件至Herbert Sutter's arguments for this to be possible in proposal N4029。
5条答案
按热度按时间j13ufse21#
答案是双重的。所有其他的答案,包括OP的自我回答,只解决了一半。
无法自动转换指针,因为:
unique_ptr
的constructor从一个指针被声明为explicit
,因此编译器只在显式上下文中考虑。这样做是为了防止意外的危险转换,其中unique_ptr
可以劫持指针并在程序员不知情的情况下删除它。一般来说,不仅对于unique_ptr
,将所有单参数构造函数声明为explicit
以防止意外转换也被认为是一个很好的实践。目前,有几种解决方法:
或
在c++14中,你也可以使用函数返回类型的自动推导:
更新:为第二点添加了委员会问题的链接。
yhived7q2#
因为从裸指针隐式构造
unique_ptr
非常容易出错。只需要显式地构造它:
8gsdolmq3#
因为
std::unique_ptr
拥有指针的所有权,你肯定不想意外地得到原始指针delete
d。如果可能的话,那么:
gblwokeq4#
因为转换或强制转换需要适当的强制转换运算符(在源类型上)或构造函数(在目标类型上)。在本例中,它是must be,下面是
unique_ptr
的构造函数:它有explicit keyword。您的
get_it()
尝试隐式转换,这是explicit
阻止的。相反,你必须显式地构造unique_ptr
,正如@Stas和@VincentSavard所建议的那样:或者,如果我们只想说一次
unique_ptr
...g0czyy6m5#
因为它很危险。
使用来自C++14的
std::make_unique()
: