#include <iostream>
#include <thread>
template<int Num>
class MyClass {
public:
MyClass(int val) : val_(val) {}
// Copy constructor
MyClass(const MyClass& other) : val_(other.val_) {
std::cout << "Copy constructor called" << std::endl;
}
// Move constructor
MyClass(MyClass&& other) noexcept : val_(other.val_) {
std::cout << "Move constructor called" << std::endl;
}
private:
int val_;
};
template<int Num>
void threadFunction(MyClass<Num> myObj) {
std::cout << "Inside thread" << std::endl;
}
int main() {
MyClass<1> obj(42);
std::thread t1(threadFunction<1>, obj); // <-- cally copy AND move
std::thread t2(threadFunction<1>, std::ref(obj)); // <-- calls only copy
t1.join();
t2.join();
return 0;
}
I know that std::ref(obj)
is actually not necessary in this example based on the answer here:
c++ thread function accepting object by value: why does std::ref(obj) compile?
However, different constructors are invoked depending on how obj is passed: copy+move constructor for obj
and only copy constructor for std::ref(obj)
.
Why is that?
std::ref
(orstd::cref
) when the thread function takes its argument by reference. Otherwise it doesn't really make sense. – Vadneestd::ref
is needed to pass objects by reference, because the thread object creates a copy, and references can't be copied. – Vadneestd::move(obj)
as argument, then a single "move" should be the only thing happening. – Vadnee