J'essaie de construire un std::thread
avec une fonction membre qui ne prend aucun argument et retourne void
. Je ne peux pas trouver de syntaxe qui fonctionne - le compilateur se plaint quoi qu'il arrive. Quelle est la bonne façon de l'implémenter spawn()
pour qu'elle renvoie un std::thread
qui s'exécute test()
?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
c++
multithreading
c++11
abergmeier
la source
la source
std::move( std::thread(func) );
est meilleure, carstd::thread
n'a pas de constructeur de copie.std::move
est redondante dans ce cas - si ce n'était pas vrai, et qu'il n'y avait pas de constructeur de copie, le compilateur donnerait quand même une erreur.Réponses:
EDIT: Pour comptabiliser votre montage, vous devez le faire comme ceci:
MISE À JOUR: Je veux expliquer quelques points supplémentaires, certains d'entre eux ont également été discutés dans les commentaires.
La syntaxe décrite ci-dessus est définie en fonction de la définition INVOKE (§20.8.2.1):
Un autre fait général que je veux souligner est que par défaut le constructeur de thread copiera tous les arguments qui lui sont passés. La raison en est que les arguments peuvent avoir besoin de survivre au thread appelant, la copie des arguments le garantit. Au lieu de cela, si vous voulez vraiment passer une référence, vous pouvez utiliser un
std::reference_wrapper
créé parstd::ref
.En faisant cela, vous promettez de prendre soin de garantir que les arguments existeront toujours lorsque le thread les opèrera.
Notez que toutes les choses mentionnées ci-dessus peuvent également être appliquées à
std::async
etstd::bind
.la source
std::thread
constructeur fonctionne comme si les arguments étaient passés àstd::bind
. Pour appeler une fonction membre, le premier argument àstd::bind
doit être un pointeur, une référence ou un pointeur partagé vers un objet du type approprié.bind
? Je ne trouve ça nulle part.Puisque vous utilisez C ++ 11, l'expression lambda est une solution agréable et propre.
puisqu'elle
this->
peut être omise, elle pourrait être raccourcie pour:ou juste
la source
std::move
lors du retour d'une variable locale par valeur. Cela inhibe en fait le RVO. Si vous retournez simplement par valeur (sans le déplacement), le compilateur peut utiliser RVO, et si ce n'est pas le cas, la norme dit qu'il doit invoquer la sémantique de déplacement.[=]
. Avec cela, vous pouvez copier par inadvertance un énorme objet. En général, c'est une odeur de code à utiliser[&]
ou[=]
.[&]
), vous pouvez introduire des bogues comme certaines références pendantes. (Par exemple,std::thread spawn() { int i = 10; return std::thread( [&] { std::cout<<i<<"\n"; } ); }
)Voici un exemple complet
La compilation avec g ++ produit le résultat suivant
la source
delete
la mémoire du tas :)@ hop5 et @RnMss ont suggéré d'utiliser des lambdas C ++ 11, mais si vous traitez avec des pointeurs, vous pouvez les utiliser directement:
les sorties
Un échantillon réécrit de cette réponse serait alors:
la source
Certains utilisateurs ont déjà donné leur réponse et l'ont très bien expliqué.
Je voudrais ajouter quelques éléments supplémentaires liés au fil.
Comment travailler avec functor et thread. Veuillez vous référer à l'exemple ci-dessous.
Le thread fera sa propre copie de l'objet en passant l'objet.
Une autre façon de réaliser la même chose est comme:
Mais si vous souhaitez passer l'objet par référence, utilisez la syntaxe ci-dessous:
la source