Home > database >  How to consume the soul of an object
How to consume the soul of an object

Time:11-05

I have a movable type that has no default constructor and I want to take away its internal data and destroy them. My thought was to std::move it to a temporary, and let the temporary destructor happen (to destroy the internal data), leaving the original now-empty object behind.

The closest I've got makes use of a little helper template that's sole purpose is to destroy its argument (which is why it's passed by value, and why the body of the function is empty.) (Maybe there's a better way?) Then I call std::move to move the internals of the original object to a temp, and the temp will be destroyed, destroying the original internals, and leaving the object in whatever state it is in after having its internals moved to another object.

template <typename T>
void reset(T t) {}
};

reset(std::move(somevar));

For example, if I had a vector of really long strings and I wanted to "free up" the memory being used by one of the strings in the middle of the vector. This is not the perfect example because string does have a parameterless constructor, but my type does not. Nevertheless this captures the spirit of my motivation for attempting this.

std::vector<std::string> vec; // suppose I have a populated vector of strings

// Let's "reset" vec[3] to an empty string by moving it to a temp and destroying the temp
reset(std::move(vec[3]));

This moves the internals of vec[3] into the argument t of the reset function, and then, the destructor for t cleans up the internals. This leaves vec[3] as an empty string.

The important part of this stunt is that we didn't need to construct an empty string. This is important because my moveable type can be moved, but cannot be default constructed.

Other things I've tried:

{ std::move(somevar); } // this doesn't work

std::move all by itself doesn't work because you have to actually put the contents somewhere.

{ T t = std::move(somevar); } // works but cumbersome, and I have to name `T`

I'm just looking for a function I can call like reset(somevar). That consumes the soul of some object. And the std::move part isn't so bad. It is kind of like the authorization of I expect you to die. So it's ok, in my mind, to say reset(std::move(somevar)) But it doesn't finish the job. So, maybe there's some other function that does do what I want.

So, is there a std::consume_soul that will accomplish the same as moving the contents of an object to a dummy and then destroing the dummy, leaving the original object behind with no contents (or whatever state the move constructor will leave it in)?

Maybe I'm unaware of some obvious approach? I feel like there's likely some super easy way I'm just not aware of.

CodePudding user response:

Moving isn’t automatic, but non-const references are, so you can write

template<class T>
void dementor(T &t) {T(std::move(t));}
  •  Tags:  
  • c
  • Related