mercredi 13 avril 2022

moving the content of a unique_ptr

So if I have a moveable (rval) std::unique_ptr, can I use simple assign to move the contents rather than copy? (The contents of the pointed to object, rather than the pointer to it)

It doesn't look like I can, but "maybe I'm doing it wrong"?

If not, what was the rationale for not allowing this?

Detail:

So I have become the owner of a class with a method that is returning the std::map from Hell, and I really don't want to include hell.h everywhere the class is used, just in the few places that really want to go there.

So my thought was to change the return signature of the method from

#include "hell.h"
std::map<std::string, Hell> CopyTheObjectSpecified(...);

To

class Hell;
std::unique_ptr<std::map<std::string, Hell>> CopyTheObjectSpecified(...);

And, for the cost of a new and delete, I now don't need to detail Hell, except when the method is called, and that code will be safely scoped by unique_ptr. Given the map copy has lots of allocations, I'm not concerned about one more.

However, one of the callers is doing:

void Angel(Hell& hell)
{
  hell = CopyTheObjectSpecified(...);
}

Which used to reduce to a move assignment (or even a complete return copy elision - probably not)

So now I'm doing one of

void Angel(Hell& hell)
{
  hell = * CopyTheObjectSpecified(...);
}

Or the move verbose, visually offensive, but trackable, and injectable almost anywhere:

void Angel(Hell& hell)
{
  hell = CopyTheObjectSpecified(...) .get()[0] ;
}

It appears to me, looking at the debugs, that the overloads of * and get() don't seem to behold that the unique_ptr is an r-val, and that the content should therefore also be returned as an r-val.

So this is invoking copy/delete semantics instead of move semantics, which is an overhead. I can;'t give it back running slower!

Of course I could simply add a std::move(), but that would be yet an extra smell when the original author gets it back.

Or I can minimally encapsulate the movability in a wrapper class for unique_ptr. Are there dangers in having a rval-content-movable unique_ptr?

Currently we code to c++11. Perhaps I need the help of the later standards to do this properly? But that may help me formulate a solution that is readable and transferable.

Grr! I just want this method /out/ of /my/ class! But that's not an option today.

Aucun commentaire:

Enregistrer un commentaire