ein*_*ica 15 c++ pointers explicit smart-pointers c++11
让我通过一个例子提出我的问题.
#include <memory>
std::unique_ptr<int> get_it() {
auto p = new int;
return p;
}
int main() {
auto up ( get_it() );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无法编译时出现以下错误:
a.cpp:5:9: error: could not convert ‘p’ from ‘int*’ to ‘std::unique_ptr<int>’
return p;
^
Run Code Online (Sandbox Code Playgroud)
为什么没有从原始指针自动转换为唯一的指针?我应该做什么呢?
动机:我理解使用智能指针清除所有权应该是一种好习惯; 我从某个地方得到一个指针(我拥有),就像int*
在这种情况下一样,我(想想我)想要它unique_ptr
.
如果您正在考虑评论或添加您自己的答案,请在提案N4029中解决Herbert Sutter关于此问题的论点.
Ily*_*pov 16
答案是双重的.所有其他答案,包括OP的自我答案,只解决了其中的一半.
指针无法自动转换,因为:
unique_ptr
声明了指针的构造函数explicit
,因此编译器仅在显式上下文中考虑它.这样做是为了防止意外的危险转换,其中一个人unique_ptr
可以劫持一个指针并在没有程序员知识的情况下删除它.一般而言,不仅仅是因为unique_ptr
将所有单参数构造函数声明为explicit
防止意外转换被认为是一种好习惯.return
明确由Herb萨特(N4029,N4074),以及两个"回应",称不这样做:Howard Hinnant和Ville Voutilainen的N4094和FilipRoséen的N4131.经过多次讨论和民意调查后,该问题被关闭为NAD - 而不是缺陷.目前,有几种解决方法:
return std::unique_ptr<int>{p};
Run Code Online (Sandbox Code Playgroud)
要么
return std::unique_ptr<int>(p);
Run Code Online (Sandbox Code Playgroud)
在c ++ 14中,您也可以使用函数返回类型的自动推导:
auto get_it() {
auto p = new int;
return std::unique_ptr<int>(p);
}
Run Code Online (Sandbox Code Playgroud)
更新:为第二点添加了委员会问题的链接.
因为unique_ptr
来自裸指针的隐式构造将非常容易出错.
只需明确构造它:
std::unique_ptr<int> get_it() {
auto p = new int;
return std::unique_ptr<int>(p);
}
Run Code Online (Sandbox Code Playgroud)
因为std::unique_ptr
它拥有指针的所有权,并且您绝对不希望delete
意外获得原始指针 d 。
如果这可能的话:
void give_me_pointer(std::unique_ptr<int>) { /* whatever */ }
int main() {
int *my_int = new int;
give_me_pointer(my_int);
// my_int is dangling pointer
}
Run Code Online (Sandbox Code Playgroud)