[英]Preventing unsafe dereferencing of std::unique_ptr
Taken from a slide at cppcon2015: 摘自cppcon2015的幻灯片:
unique_ptr<A> f() {
auto a = make_unique<A>();
return a;
}
//Why does this even compile?
const A & dangling = *f();
//BOOM!!!
use(dangling);
My question is: with rvalue references for *this, can this be solved? 我的问题是:对于* this的rvalue引用,这可以解决吗?
I see in the spec in cppreference: 我在cppreference的spec中看到:
typename std::add_lvalue_reference<T>::type operator*() const;
Question: 题:
operator*
for rvalue unique_ptr
s and only have dereference valid for lvalue unique_ptr
s? 是否允许operator*
为rvalue unique_ptr
而且只有对于左值unique_ptr
s有效的解除引用才有意义吗? unique_ptr
dereferenceable? 还有一些有效的用例可以保持rvalue unique_ptr
解除引用吗? Like this: 像这样:
//Make sure it is an lvalue.
typename std::add_lvalue_reference<T>::type operator*() const &;
NOTE: I am not sure of the syntax or correctness, I have no experience with rvalue references for *this. 注意:我不确定语法或正确性,我对* this的rvalue引用没有经验。
My question is: with rvalue references for
*this
, can this be solved? 我的问题是:对于*this
rvalue引用,这可以解决吗?
Technically yes. 技术上是的。 One solution would be to introduce an additional (deleted) overload for rvalues: 一种解决方案是为rvalues引入一个额外的(删除的)重载:
typename std::add_lvalue_reference<T>::type operator*() const&& = delete;
// ~~~~~~~~~~~~~~~^
and to modify the existing one by means of adding a ref-qualifier: 并通过添加ref-qualifier来修改现有的:
typename std::add_lvalue_reference<T>::type operator*() const&;
// ~~^~~
Since rvalues strongly prefer to be bound by an rvalue reference, any attempt to dereference an rvalue expression involving a unique_ptr
would result in a compile error - "use of deleted function". 由于rvalues强烈倾向于被rvalue引用绑定,因此任何尝试取消引用涉及unique_ptr
的rvalue表达式都会导致编译错误 - “使用已删除的函数”。
Would it make sense to disallow
operator*
for rvalueunique_ptrs
and only have dereference valid for lvalueunique_ptrs
? 为rvalueunique_ptrs
禁用operator*
并且只对lvalueunique_ptrs
有效取消引用是否有意义?
Not always. 不总是。 And because of that I doubt the library should impose additional constraints on the unique_ptr
specification, only to prevent a possible misuse. 因此,我怀疑库应该对unique_ptr
规范施加额外的限制,只是为了防止可能的误用。
There are still valid use cases to keep the rvalue
unique_ptr
dereferenceable? 还有一些有效的用例可以保持rvalueunique_ptr
解除引用吗?
The lifetime of a temporary ends at the end of a full expression that the temporary is part of. 临时的生命周期在临时属于完整表达式的末尾结束。 This means that the object obtained from dereferencing a unique_ptr
is valid as long as the associated unique_ptr
is alive, so the below use-cases are valid, and wouldn't be possible if operator*
was disabled for rvalues: 这意味着只要关联的unique_ptr
处于活动状态,从解除引用unique_ptr
获得的对象就是有效的,因此下面的用例是有效的,如果对rvalues禁用operator*
则不可能:
(*f()).foo();
// ^~~ unique_ptr is destroyed here
use(*f());
// ^~~ unique_ptr is destroyed here
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.