Prevent unsafe dereferencing std :: unique_ptr

Taken from slide at 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 links for * this, can this be solved?

I see in the specification in cppreference:

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

Question:

  • Would it be prudent to disable operator* for rvalue unique_ptr and have only the splitting valid for lvalue unique_ptr s?
  • Are there still valid use cases to preserve the value of rvalue unique_ptr ?

Like this:

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

NOTE. I'm not sure about the syntax or the correctness, I have no experience with rvalue links for this.

+5
source share
1 answer

My question is: with rvalue links for *this , can this be solved?

Technically, yes. One solution would be to introduce an additional (remote) overload for r values:

 typename std::add_lvalue_reference<T>::type operator*() const&& = delete; // ~~~~~~~~~~~~~~~^ 

and modify the existing one by adding ref-qualifier:

 typename std::add_lvalue_reference<T>::type operator*() const&; // ~~^~~ 

Since rvalues ​​strongly prefer rvalue to link, any attempt to dereference an rvalue expression that includes unique_ptr will result in a compilation error - "using a remote function".

Would it be prudent to disable operator* for rvalue unique_ptrs and have only the difference valid for lvalue unique_ptrs ?

Not always. And because of this, I doubt that the library should impose additional restrictions on the unique_ptr specification, only to prevent possible abuse.

Are there still valid use cases to preserve the value of rvalue unique_ptr ?

The lifetime of a temporary object ends at the end of the full expression, which is temporary. This means that the object obtained by dereferencing a unique_ptr is valid as long as the associated unique_ptr is supported, so the given usage examples are valid and will not be possible if operator* disabled for rvalues:

 (*f()).foo(); // ^~~ unique_ptr is destroyed here use(*f()); // ^~~ unique_ptr is destroyed here 
+3
source

Source: https://habr.com/ru/post/1232074/


All Articles