[英]Preventing unsafe dereferencing of std::unique_ptr
摘自cppcon2015的幻灯片:
unique_ptr<A> f() {
auto a = make_unique<A>();
return a;
}
//Why does this even compile?
const A & dangling = *f();
//BOOM!!!
use(dangling);
我的问题是:对于* this的rvalue引用,这可以解决吗?
我在cppreference的spec中看到:
typename std::add_lvalue_reference<T>::type operator*() const;
题:
operator*
为rvalue unique_ptr
而且只有对于左值unique_ptr
s有效的解除引用才有意义吗? unique_ptr
解除引用吗? 像这样:
//Make sure it is an lvalue.
typename std::add_lvalue_reference<T>::type operator*() const &;
注意:我不确定语法或正确性,我对* this的rvalue引用没有经验。
我的问题是:对于
*this
rvalue引用,这可以解决吗?
技术上是的。 一种解决方案是为rvalues引入一个额外的(删除的)重载:
typename std::add_lvalue_reference<T>::type operator*() const&& = delete;
// ~~~~~~~~~~~~~~~^
并通过添加ref-qualifier来修改现有的:
typename std::add_lvalue_reference<T>::type operator*() const&;
// ~~^~~
由于rvalues强烈倾向于被rvalue引用绑定,因此任何尝试取消引用涉及unique_ptr
的rvalue表达式都会导致编译错误 - “使用已删除的函数”。
为rvalue
unique_ptrs
禁用operator*
并且只对lvalueunique_ptrs
有效取消引用是否有意义?
不总是。 因此,我怀疑库应该对unique_ptr
规范施加额外的限制,只是为了防止可能的误用。
还有一些有效的用例可以保持rvalue
unique_ptr
解除引用吗?
临时的生命周期在临时属于完整表达式的末尾结束。 这意味着只要关联的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.