std::thread Calls Copy Constructor When Passing by Reference
Passing data into a thread using std::thread can be problematic, especially when dealing with classes that have disabled copy constructors. This behavior stems from the fact that std::thread takes its arguments by value.
Consider the following class Log with a disabled copy constructor:
class Log { public: Log(const char filename[], const bool outputToConsole = false); virtual ~Log(void); // ... private: // Disable copy constructor and assignment operator Log(const Log &); Log &operator=(const Log &); };
In the main function, the Log object logger is passed by reference to the server function:
Log logger("ServerLog.txt", true); server(ioService, portNumber, logger);
The server function then creates a new thread with logger as an argument:
std::thread newThread(session, &sock, logger);
However, this causes a compiler error due to the disabled copy constructor in Log.
Why Does Passing by Reference Call the Copy Constructor?
Contrary to common assumptions, passing by reference in C does not prevent the invocation of the copy constructor. When passing a reference, the compiler creates a temporary copy of the referred object and passes it to the function. This is because std::thread expects its arguments to be copyable.
Solution: Using std::reference_wrapper
To achieve reference semantics in this scenario, you can use std::reference_wrapper:
std::thread newThread(session, &sock, std::ref(logger));
std::ref wraps a reference in a way that makes it appear as a copyable object to std::thread. However, you must ensure that the lifetime of the underlying object (in this case, logger) extends beyond the lifetime of the thread.
The above is the detailed content of Why Does std::thread Call the Copy Constructor Even When Passing by Reference?. For more information, please follow other related articles on the PHP Chinese website!