3 ms·
Instead of trying to reason about the copying and moving of huge objects, I give my brain a break by using std::unique_ptr<HugeObject>. unique_ptr is moveable,
by thrownaway2424 11y ago
Instead of trying to reason about the copying and moving of huge objects, I give my brain a break by using std::unique_ptr<HugeObject>. unique_ptr is moveable, cannot accidentally be copied (because its copy constructor is private), and is trivially small. unique_ptr also gets around the problem where the compiler can't figure out which value is being RVO'd, because you can do this:
std::unique_ptr<BigObject> Blerg(yourmom) {
std::unique_ptr<BigObject> big_object_ptr;
BigObject foo, bar;
if (2 > yourmom) {
big_object_ptr.reset(foo);
} else {
big_object_ptr.reset(bar);
}
return std::move(big_object_ptr);
}
This isn't valid code but it's pretty close.
- mgraczyk 11y agoThis doesn't help to solve the original problem of avoiding the copy. Your calls to big_object_ptr.reset(...) will cause the BigObject copy constructor to be called. The object pointed to by unique_ptr does not have the same storage as the objects "foo" and "bar". At the very least, you need to do big_object_ptr.reset(std::move(foo)); which will cause foo to be moved into the unique_ptr's storage. In code like this, you should just use make_unique, in which case the BigObject is constructed in place, and unique_ptr can be RVO'ed: if (...) { return make_unique<BigObject>(...); } else ...
- thrownaway2424 11y agoYeah I realized after the fact that the example is pointless, but I was trying to adhere to the original post, which is also pointless. Why would you construct two BigObject when you know you will discard one of them unused? It's dumb.
- shin_lao 11y agoYour code implies the use of heap memory, with values you can work only on the stack.
- abhishekkr 11y agoYou can actually just do return big_object_ptr; Instead of the std::move. The compiler will complain if it can't do RVO because unique_ptr prohibits a copy, so you're safe :)
- mavam 11y ago> I give my brain a break by using std::unique_ptr<HugeObject>. Unfortunately this comes at a cost. Most notably, now you're unnecessarily stressing the allocator. But worse, you no longer enjoy the benefits of value semantics [1]. [1] https://akrzemi1.wordpress.com/2012/02/03/value-semantics/ https://akrzemi1.wordpress.com/2012/02/03/value-semantics/