Std :: unique_ptr :: release () vs std :: move ()

I have a class representing the runtime context and creating a tree, the root of the tree is stored in unique_ptr . When you build a tree, I want to extract a tree. Here's what it looks like (doesn't work, it's not a debugging issue):

 class Context { private: std::unique_ptr<Node> root{new Node{}}; public: // imagine a constructor, attributes and methods to build a tree std::unique_ptr<Node> extractTree() { return std::move(this->root); } }; 

So, I used std::move() to extract the root of the node from the Context instance.

However, there are alternatives to using std::move() for example:

 std::unique_ptr<Node> extractTree() { // This seems less intuitive to me return std::unique_ptr<Node>{this->root.release()}; } 

Is std::move() better choice?

+6
source share
2 answers

You should definitely upgrade to the first version, as the second basically does everything the first version does, with more code and less readability.

From a philosophical point of view, the second version moves a unique pointer, neither more nor less. so why go around the table instead of using an existing, more readable, and more idiomatic std::unique_ptr(std::unique_ptr&&) ?

And finally, if your smart pointer somewhere in the future contains a custom removal tool, the first version will make sure that the removal tool also moves, and the second version does not move the removal tool. I can definitely imagine a programmer creating a non-standard pointer to a unique remover from a non-standard remover unique_pointer using release . With relocation semantics, the program cannot compile.

+4
source

What you do is dangerous. After you getTree() , you should not call it a second time, which is not clear from the interface. You might want to rethink your design (for example, shared_ptr can do a better job or just save the root as an unprocessed pointer and take care of freeing it up manually).

In any case, using std::move is the best option for the two if you want to stick with your design, as that makes your intention clearer.

EDIT: Apparently, "should not" has a special meaning of prohibition in English, which I did not know about. This is normal if you call the function twice or as many times as you want, but you will not return a pointer to a valid object if it is done sequentially.

+3
source

All Articles