Moving semantics and constant references

I spent quite a bit of time implementing movement semantics for my class, but now I am dealing with functions that use it.

Ok, so I have this object with a lot of data on the heap: CLargeOb , for which I implemented move semantics (constructor and operator =). It fits perfectly as follows:

 void OtherOb::Func(CLargeOb&& largeOb1, CLargeOb&& largeOb2) { SomeOtherFunc(largeOb1); // use objects SomeOtherFunc(largeOb2); m_largeOb1 = (CLargeOb&&)largeOb1; // save as members and trash the originals m_largeOb2 = (CLargeOb&&)largeOb2; } 

However, it is not always possible to allow moving / splitting objects, so I added these two functions:

 void OtherOb::Func(const CLargeOb& largeOb1, CLargeOb&& largeOb2) { SomeOtherFunc(largeOb1); SomeOtherFunc(largeOb2); m_largeOb1 = largeOb1; m_largeOb2 = (CLargeOb&&)largeOb2; } void OtherOb::Func(CLargeOb&& largeOb1, const CLargeOb& largeOb2) { SomeOtherFunc(largeOb1); SomeOtherFunc(largeOb2); m_largeOb1 = (CLargeOb&&)largeOb1; m_largeOb2 = largeOb2; } 

Although it works, you can already guess that this will become a major pain in ss when I have a function that takes 3 or more of these objects as parameters ... Is there no sensible way to solve this problem with patterns or maybe "perfect call forwarding"?

+7
source share
1 answer

As in C ++ 03, the manual: if you want to get a copy, enter it in the parameter list .

This allows the caller to deal with how you receive the object, you simply receive the object independently:

 void OtherOb::Func(CLargeOb largeOb1, CLargeOb largeOb2) { SomeOtherFunc(largeOb1); // use objects SomeOtherFunc(largeOb2); m_largeOb1 = std::move(largeOb1); // save as members and trash the originals m_largeOb2 = std::move(largeOb2); // (you should use std::move, not cast) } 

Defiant:

 OtherOb o; CLargeOb x, y; const CLargeOb z; o.Func(x, std::move(y)); // need x for later, done with y so move it o.Func(std::move(x), z); // done with x, necessarily copy z 

It is as effective as several specialized overloads. What for? Because they already exist in the class as constructors. Let the compiler figure out why to call the call site, he already knows what to do.

+15
source

All Articles