In your case, obj copied:
- Twice on a call to
std::async . - Twice on
async internal call to std::bind . - Once upon a call
void foo(obj a) , since it takes the value a by value.
Believe it or not, the number of copies has actually been reduced from the VC10 .
It is not unusual for a library (whether it be a standard library or another) to run multiple copies than you would expect from your types. And, as a rule, not much can be done in this.
There are two things that people usually do to prevent copying:
- Take
obj by reference (or in your case, const ref, since foo does not change obj ). This will require using std::ref with asynchronism. - Define a move constructor for
obj . This will not prevent the creation and destruction of temporary objects, but it will give you the opportunity to optimize the process a bit.
Please note that in your bare example of an object that contains only one int , it is more likely to copy than move or pass by reference.
Example for passing obj by reference in async :
void foo(const 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, std::cref(a)); future.wait(); return 0; }
An example of the definition of a move constructor
class obj { public: obj(obj&& a) : val(move(a.val)) { // It is good practice to 0 out the moved object to catch use-after-move bugs sooner. a.val = 0; } };
Sean cline
source share