std::thread appelle le constructeur de copie lors du passage par référence
Transmettre des données dans un thread à l'aide de std::thread peut être problématique, en particulier lorsqu'il s'agit de classes qui ont désactivé les constructeurs de copie. Ce comportement vient du fait que std::thread prend ses arguments par valeur.
Considérez la classe Log suivante avec un constructeur de copie désactivé :
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 &); };
Dans la fonction principale, le Log object logger est passé par référence à la fonction serveur :
Log logger("ServerLog.txt", true); server(ioService, portNumber, logger);
La fonction serveur crée ensuite un nouveau thread avec logger comme argument :
std::thread newThread(session, &sock, logger);
Cependant, cela provoque une erreur du compilateur en raison du constructeur de copie désactivé dans le journal.
Pourquoi le passage par référence appelle-t-il le constructeur de copie ?
Contrairement aux hypothèses courantes, le passage par référence en C n'empêche pas l'invocation du constructeur de copie. Lors du passage d'une référence, le compilateur crée une copie temporaire de l'objet référencé et la transmet à la fonction. En effet, std::thread s'attend à ce que ses arguments soient copiables.
Solution : Utilisation de std::reference_wrapper
Pour obtenir une sémantique de référence dans ce scénario, vous pouvez utiliser std::reference_wrapper:
std::thread newThread(session, &sock, std::ref(logger));
std::ref encapsule une référence de manière à ce que il apparaît comme un objet copiable dans std :: thread. Cependant, vous devez vous assurer que la durée de vie de l'objet sous-jacent (dans ce cas, l'enregistreur) s'étend au-delà de la durée de vie du thread.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!