防止std :: unique_ptr的不安全解除引用

时间:2015-09-23 07:16:01

标签: c++ c++11 c++14 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的规范中看到了:

typename std::add_lvalue_reference<T>::type operator*() const;

问题:

  1. 对于右值operator*禁用unique_ptr是否有意义且只有对于左值unique_ptr s有效的取消引用?
  2. 仍有有效的用例可以使rvalue unique_ptr取消引用吗?
  3. 像这样:

    //Make sure it is an lvalue.
    typename std::add_lvalue_reference<T>::type operator*() const &;
    

    注意:我不确定语法或正确性,我对* this的rvalue引用没有经验。

1 个答案:

答案 0 :(得分:3)

  

我的问题是:使用*this的右值引用,这可以解决吗?

技术上是的。一种解决方案是为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表达式的尝试都会导致编译错误 - “使用已删除的函数”。

  

对于右值operator*禁止使用unique_ptrs并且只对左值unique_ptrs有效取消引用是否有意义?

并非总是如此。因此我怀疑库应该对unique_ptr规范施加额外的限制,只是为了防止可能的滥用。

  

还有一些有效的用例可以让rvalue unique_ptr取消引用?

临时的生命周期在临时属于完整表达式的末尾结束。这意味着只要关联的unique_ptr处于活动状态,从解除引用unique_ptr获得的对象就是有效的,因此以下用例是有效的,如果operator*则不可能。已被禁用为右值:

(*f()).foo();
//          ^~~ unique_ptr is destroyed here


use(*f());
//       ^~~ unique_ptr is destroyed here