C++11 std::thread donnant error: no matching function appel à std::thread::thread
Je suis en essais c++11 fils avec ce code, mais lors de la création du thread, je vais avoir l'erreur no matching function for call to 'std::thread::thread()'.
C'est comme si il y avait quelque chose de mal avec la fonction que je suis en train de donner à std::thread ctr, mais je ne vois pas en quoi c'est mal. Il est inachevées, mais il regarde à droite pour moi:
En-tête:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <thread>
#include <mysql++.h>
class Connection
{
public:
Connection(std::string mysqlUser, std::string mysqlPassword);
~Connection();
private:
std::string mysqlUser;
std::string mysqlPassword;
std::string mysqlIP;
int mysqlPort;
mysqlpp::Connection mysqlConnection;
std::thread connectionThread;
void threadLoop();
};
#endif //CONNECTION_H
Source:
#include "connection.h"
Connection::Connection(std::string mysqlUser, std::string mysqlPassword)
{
this->mysqlUser = mysqlUser;
this->mysqlPassword = mysqlPassword;
this->mysqlIP = "localhost"; //default
this->mysqlPort = 3306; //default
//Launch thread
std::thread connectionThread(threadLoop);
}
Connection::~Connection(){
mysqlConnection.disconnect();
}
void Connection::threadLoop(){
//Connect to mySQL database
mysqlConnection = new mysqlpp::Connection(false);
if(mysqlConnection.connect(NULL, mysqlIP.c_str(), mysqlUser.c_str(), mysqlPassword.c_str(), mysqlPort)){
std::string consulta = "SELECT * FROM 'Coordinates'";
mysqlpp::Query query = mysqlConnection.query(consulta);
mysqlpp::StoreQueryResult res = query.store();
query.reset();
}
while(true){
//Stuff
}
}
Veuillez fournir une complète minimale de l'échantillon du programme. À partir de votre description, il doit être dans les 5 à 10 lignes. Voir SSCCE.ORG.
Ne pas
Le compilateur que vous utilisez?
Je pense que vous devriez vous tourner que dans une réponse.
Vous êtes à la déclaration d'un nouvel objet thread i n de votre constructeur. Je me doute que c'est ce que vous souhaitez.
Ne pas
std::thread
'constructeur s'attendre à une fonction ou à tout le moins une fonction membre statique? Comment peut-il savoir sur quel objet pour appeler Connection::threadLoop
?Le compilateur que vous utilisez?
Je pense que vous devriez vous tourner que dans une réponse.
Vous êtes à la déclaration d'un nouvel objet thread i n de votre constructeur. Je me doute que c'est ce que vous souhaitez.
OriginalL'auteur Roman Rdgz | 2012-09-27
Vous devez vous connecter pour publier un commentaire.
Le problème est que
threadLoop
est une fonction membre, mais il n'y a pas d'objet pour qu'il soit appliqué. Juste deviner:Mais c'est juste la syntaxe problème; il y a un problème de logique, trop: cette ligne crée un objet local de type
std::thread
qui disparaît lorsque la fonction retourne. Son destructeur va appelerstd::terminate()
parce que le fil n'a pas été jointes. Le plus probable, ce devait attacher un fil à laconnectionThread
membre. Pour ce faire:terminate()
directement, selon le §30.3.1.3 dans la norme. Pas une bonne chose en tout cas. Et ce sera également se produire que si lesconnectionThread.join()
est finalement appelé.merci pour la correction. J'ai mis à jour ma réponse.
Il ne fonctionne pas, et je ne comprends pas pourquoi je dois passer une référence à la classe de Connexion avec "ce": la référence dit que je devrais passer une fonction et les arguments optionnels. Veuillez expliquer si je suis absent quelque chose
en quoi n'est-ce pas le travail? Un membre de la fonction ne peut être appelée avec un objet. Lorsque vous passez un pointeur de fonction membre dans le
thread
constructeur, vous devez aussi lui donner un objet. Qui peut être lui même un objet, une référence à un objet, un pointeur vers un objet (commethis
), ou quelque chose qui peut être déréférencé pour obtenir un pointeur ou une référence à un objet (généralement un pointeur intelligent).Grâce à @Dodgie pour la correction de l'ajout de
&Connection::
à la construction deconnectionThread
. Je ne sais pas pourquoi la révision proposée a été rejetée.OriginalL'auteur Pete Becker
Votre code a deux problèmes:
std::thread
constructeurstd::thread
avant il est joint avec le thread principal.Pour le premier problème, comme Pete Becker suggère, vous devez fournir l'objet sur lequel la fonction est appelée, parce que le constructeur de
std::thread
a pas d'autre moyen de le savoir. En supposant que vous voulez l'appeler la fonctionthreadLoop()
sur leConnection
objet que vous êtes en train de construire, vous pouvez le faire:En interne, le constructeur d'appel
this->threadLoop()
(oùthis
est leConnection*
paramètre qu'il a reçu, ne lestd::thread
lui-même, bien sûr). Et vous serez amende.Le deuxième problème, c'est que votre
std::thread
est détruite immédiatement après le démarrage, sans avoir adhéré à l'initiative pour le thread principal: cela appelterminate()
, ce qui n'est pas une bonne chose. Encore une fois, Pete suggère une bonne alternative. Remplacer le code ci-dessus avec ceci:La situation avant ce code est comme suit:
std::thread
objet,connectionThread
, qui ne constitue pas réellement un threadAprès l'exécution de la première ligne de code:
connectionThread
std::thread
objetthr
, qui sera détruite à la fin de laConnection
constructeur, provoquant un appel àterminate()
parce qu'il n'est jamais rejoint le thread principal.Heureusement, la deuxième ligne de code vient à la rescousse. Après son exécution:
std::thread
,thr
, qui peuvent être détruits en toute sécurité car il ne représente pas un véritable fil conducteur (donc il n'est pas joignable)connectionThread
, un objet qui ne sera pas détruit tant que leConnection
objet existe.Maintenant, le problème, c'est que vous voulez vous joindre à
connectionThread
pour le thread principal avant, il est détruit, mais vous voulez aussi éviter de bloquer le thread principal. Le bon moment pour faire cette jointure est le dernier moment: lorsqu'connectionThread
est sur le point d'être détruit. Et ce qui se passe au destructeur deConnection
. Donc, nous allons ajouter une ligne à cette destructeur, de cette façon:En outre, c'est l'endroit le plus sûr pour appeler
join()
, car il garantit que vous n'aurez plus jamais détruire un nonconnectionThread
. C'est RAII dans l'action; si vous n'êtes pas familier avec le concept de RAII (ou RIIA, comme on l'appelle parfois), vous pouvez trouver beaucoup d'informations à propos de cette notion très importante dans le web, y compris ce site.Tout cela mis ensemble: la création d'un
Connection
objet de créer un nouveau thread; dans ce fil, une connexion de base de données sera mis en place et une requête est exécutée, alors que le thread principal reste libre pour tout autre usage (par exemple, la gestion de l'interface graphique). Lorsque leConnection
objet est finalement détruit, le thread principal va attendre que le thread supplémentaire à la fin (si nécessaire), puis l'exécution normale continuera. J'espère que c'est ce que vous voulez accomplir avec votre code.OriginalL'auteur Gorpik
Comme vous l'avez peut manifester de cppreference,
std::thread
'constructeur s'attendre à une certaine forme de la fonction; vous pouvez passer gratuitement une fonction, une fonction membre statique ou de l'un de ces paniers, de concert avec ses arguments par des moyens destd::bind
. Pour exécuter un non-fonction membre statique, vous devez utiliserstd::mem_fn
à passer ensemble avec l'objet qu'il doit être appelé.std::bind
oustd::men_fn
ici;std::thread
'constructeur sait comment traiter avec les fonctions de membres. Le problème est qu'il n'y a pas d'objet pour la fonction de membre à être appliqué.Je vois. Je n'ai pas la norme à portée de main et cppreference n'est pas très claire sur ce sujet.
cppreference est tout à fait clair, mais c'est faux. <g> Pour TR1, nous avons inventé l'INVOQUER la terminologie pour décrire comment
bind
etfunction
gérer les différentes appelable types, y compris les pointeurs de fonctions membres (le deuxième argument doit être un objet, une référence à un objet, ou un pointeur vers un objet d'un type approprié).std::thread::thread(Fn&&, Args&&...)
utilise le même mécanisme.Je suis de lecture de la norme maintenant et de voir que vous êtes de droite. Et maintenant que j'ai lu votre commentaire et de voir que tu l'avais déjà expliqué le mécanisme 🙂
Je ne comprends pas pourquoi donner std::thread() une fonction libre des œuvres, et à l'aide d'une fonction déclarée dans une classe qui ne fonctionne pas. De toute façon, Si j'ai fait ma fonction libre, hors de la classe, cela ne fonctionne toujours pas
OriginalL'auteur Nicola Musatti