samedi 3 janvier 2015

Why dtors of functors called twice, when passed to a thread as the argument for Function?

I'm having this question because of the following example:



#include <utility>
#include <thread>
#include <iostream>

typedef struct foo{
foo() = default;
void operator()(int i) const {}
~foo(){std::cout<<"dtor\n";}
} foo;

typedef struct bar{
bar() = default;
bar(const bar&) {std::cout<<"copy\n";}
bar(bar&&) {std::cout<<"move\n";}
void operator()(const foo& f, int k) const {f(k);}
~bar(){std::cout<<"bar\n";}
} bar;

int main(){
foo f_1, f_2;
bar b_1, b_2;
int i(0), j(0);
while(i++!=2){
std::thread t(b_1, std::cref(f_1), i);
b_2(f_2, j);
t.join();
}
int dummy(0);
std::cin >> dummy;
}


which yields (both gcc and clang give the same result)



copy
move
bar
bar
copy
move
bar
bar
0
bar
bar
dtor
dtor


, where the 0 is user input.


So the dtor for bar--the argument for Function--is called twice after the tread finishes its job (for each iteration). What I don't understand, is why twice instead of just once(for making the copy)?


In addition, is it possible to avoid the copy, in case the functor itself holds non-copiable resources or is expensive to be copied?


Thank you!


Aucun commentaire:

Enregistrer un commentaire