std::thread Calls Copy Constructor When Passing by Reference
Mengirim data ke dalam thread menggunakan std::thread boleh menjadi masalah, terutamanya apabila berurusan dengan kelas yang telah melumpuhkan pembina salinan. Tingkah laku ini berpunca daripada fakta bahawa std::thread mengambil argumennya mengikut nilai.
Pertimbangkan Log kelas berikut dengan pembina salinan yang dilumpuhkan:
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 &); };
Dalam fungsi utama, Log logger objek diluluskan dengan merujuk kepada fungsi pelayan:
Log logger("ServerLog.txt", true); server(ioService, portNumber, logger);
Fungsi pelayan kemudian mencipta benang baharu dengan logger sebagai hujah:
std::thread newThread(session, &sock, logger);
Walau bagaimanapun, ini menyebabkan ralat pengkompil disebabkan oleh pembina salinan yang dilumpuhkan dalam Log.
Mengapa Melewati Rujukan Memanggil Pembina Salin?
Bertentangan dengan andaian biasa, lulus melalui rujukan dalam C tidak menghalang seruan pembina salinan. Apabila menghantar rujukan, pengkompil mencipta salinan sementara objek yang dirujuk dan menghantarnya ke fungsi. Ini kerana std::thread menjangkakan hujahnya boleh disalin.
Penyelesaian: Menggunakan std::reference_wrapper
Untuk mencapai semantik rujukan dalam senario ini, anda boleh menggunakan std::reference_wrapper:
std::thread newThread(session, &sock, std::ref(logger));
std::ref membungkus rujukan dengan cara yang menjadikannya kelihatan sebagai objek yang boleh disalin ke std::thread. Walau bagaimanapun, anda mesti memastikan bahawa jangka hayat objek asas (dalam kes ini, pembalak) melangkaui hayat benang.
Atas ialah kandungan terperinci Mengapakah std::thread Memanggil Pembina Salin Walaupun Semasa Melalui Rujukan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!