I am trying to execute an object's method in a C++ thread.
I am able to do it, by passing the method's address and the object (or the object's address, or std::ref(my_obj)) to the thread's constructor.
I observed that if I pass the object, rather than the object's address or std::ref(my_obj), then the object gets copied twice (I'm printing some info in the copy constructor to see that).
Here is the code:
class Warrior{
string _name;
public:
// constructor
Warrior(string name): _name(name) {}
// copy constructor (prints every time the object is copied)
Warrior(const Warrior & other): _name("Copied " + other._name){
cout << "Copying warrior: \"" << other._name;
cout << "\" into : \"" << _name << "\"" << endl;
}
void attack(int damage){
cout << _name << " is attacking for " << damage << "!" << endl;
}
};
int main(){
Warrior conan("Conan");
// run conan.attack(5) in a separate thread
thread t(&Warrior::attack, conan, 5);
t.join(); // wait for thread to finish
}
The output I get in this case is
Copying warrior: "Conan" into : "Copied Conan"
Copying warrior: "Copied Conan" into : "Copied Copied Conan"
Copied Copied Conan is attacking for 5!
While if I simply pass &conan or std::ref(conan) as a second argument to thread t(...) (instead of passing conan), the output is just:
Conan is attacking for 5!
I have 4 doubts:
Why is that I have 2 copies of the object instead of 1?
I was expecting that by passing the instance of the object to the thread's constructor, the object would get copied once in the thread's own stack, and then the
attack()method would be called on that copy.What is the exact reason why the thread's constructor can accept an object, an address, or a
std::ref? Is it using this version of the constructor (which I admit I do not fully understand)template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );in all 3 cases?
If we exclude the first case (since it's inefficient), what should I use between
&conanandstd::ref(conan)?Is this somehow related to the syntax required by
std::bind?