2016-07-27 5 views
1

J'essaye de créer un objet qui peut recevoir une fonction et ses paramètres à son constructeur. Cette classe appellera alors la fonction donnée à l'intérieur d'un lambda qui est plutôt passé à un thread. Quelque chose le long des lignes deFonction d'appel à l'intérieur d'un lambda passé à un thread

class worker { 
public: 
    template <class Fn, class... Args> 
    explicit worker(Fn f, Args ... args) { 
     t = std::thread([&]() -> void { 
       f(args...); 
     }); 
    } 
private: 
    std::thread t; 
}; 

int main() { 
    worker t([]() -> void { 
     for (size_t i = 0; i < 100; i++) 
      std::cout << i << std::endl; 
    }); 

    return 0; 
} 

Mais je reçois l'erreur suivante

error: parameter packs not expanded with '...': f(args...); 

Qu'est-ce que je fais mal ici? Toute aide serait appréciée.

+5

Quel compilateur? Indépendant de l'erreur de votre compilateur, mais vous devez savoir que le code tel qu'il est écrit va probablement aboutir à un comportement indéfini, car le lambda capture par référence, est déplacé dans un thread, puis la portée où les données sont valides est laissée. – Yakk

+3

On dirait que vous avez trop d'accolades. – TartanLlama

+2

Votre code ne compile pas comme il est, il y a des crochets partout, 't' n'est pas déclaré, ... Après le nettoyage, je n'ai aucun problème pour compiler ceci, donc vous devriez fournir un [MCVE] (http://stackoverflow.com/help/mcve). – Holt

Répondre

2

Comme dit dans les commentaires, cette compilation très bien avec gcc-4.9 (et plus), mais si vous devez utiliser gcc-4.8 vous pouvez ajouter des paramètres au lambda dans le constructeur worker et passer les arguments par le constructeur std::thread :

class worker { 
public: 
    template <class Fn, class... Args> 
    explicit worker(Fn f, Args ...args) { 
     t = std::thread([f](Args ...largs) -> void { 
       f(largs...); 
     }, std::move(args)...); 
    } 
private: 
    std::thread t; 
}; 

cela permettra également de créer une copie des arguments dans les arguments lambda, contrairement à la capture par référence que vous utilisiez [&] qui était probablement incorrect dans ce cas (voir le commentaire @Yakk).

+0

Merci cela a fonctionné! – Aram

+0

Juste un exemple de jouet que je connais mais sans joindre ou détacher ce fil, votre main va faire un appel inattendu à 'terminate()' ... –