This question (code below) std::async and object copy got me thinking about copy/move heavy library implementations. This ones makes 5 copies for example. Countermeasures can be tricky, like in the case of async where passing by reference as opposed to value can cause concurrency problems. Move constructors are also not always cheap.
My question is could countermeasures like finding a way to pass by reference really be solving a problem that isn't there? I assume that most if not all of the library functions will end up being inlined, they are often only one or two lines of code. I of course still get five "delete obj" in output because the compiler has to follow the as if rule. If I were to take away the side effect of the destructor, by not printing, would the as if rule go further and end up with only one copy/move in release builds?
Are there things I should watch out for when writing move constructors as to not confuse the compiler or unintentionally introduce side effects and stop it from optimization?
class obj {
public:
int val;
obj(int a) : val(a) {
cout << "new obj" << endl;
}
~obj() {
cout << "delete obj" << endl;
}
};
void foo(obj a) {
this_thread::sleep_for(chrono::milliseconds(500));
cout << a.val << endl;
}
int main(int argc, int **args) {
obj a(5);
auto future = async(foo, a);
future.wait();
return 0;
}