2016-06-14 2 views
0

J'ai donc une classe appelée Delegate qui peut stocker un tableau de pointeurs de fonction. Voici le code:Tableau de pointeurs de fonction (y compris les fonctions membres) erreur de spécialisation du modèle de lancement

template<typename Func> 
class delegate 
{ 
private: 
public: 
    typename std::vector<Func> mListOfFunctions; 
    void Bind(Func f) 
    { 
     mListOfFunctions.push_back(f); 
    } 
    template<typename...TArgs> 
    void Invoke(TArgs&&...arg) 
    { 
     for (auto f : mListOfFunctions) 
     { 
      f(std::forward<TArgs>(arg)...); 
     } 
    } 
}; 

Utilisation dans Player.cpp:

delegate<void(float)> testDelegate; 
testDelegate.Bind(std::bind(&Player::MoveLeft,this)); 

Cela jette l'erreur C2893 (Erreur C2893 Impossible de se spécialiser « de type inconnu modèle de fonction std :: Invoke (_Callable & & , _types & & ...) ')

Mais quand je change la définition de Bind à ce qui suit:

template<typename F>  
void Bind(F f) 
    { 

    } 

Cela fonctionne très bien, mais lorsque j'essaie de pousser l'objet fonction dans le vecteur, il renvoie à nouveau la même erreur. Y a-t-il une solution à ce problème? J'ai besoin de mettre en cache les pointeurs passés

Répondre

0

Le résultat de std::bind n'est pas un pointeur de fonction (c'est un objet fonction d'un type non spécifié), mais vous essayez de le faire en un seul. Puisque vous utilisez std::forward, vous devez utiliser C++ 11, ce qui signifie que vous pouvez utiliser std::function:

template<typename Func> 
class delegate 
{ 
private: 
public: 
    typename std::vector<std::function<Func>> mListOfFunctions; 
    void Bind(std::function<Func> f) 
    { 
     mListOfFunctions.push_back(f); 
    } 
    template<typename...TArgs> 
    void Invoke(TArgs&&...arg) 
    { 
     for (auto f : mListOfFunctions) 
     { 
      f(std::forward<TArgs>(arg)...); 
     } 
    } 
}; 
+0

je l'ai changé à ce qui suit et il jette encore une erreur: void Bind (std :: fonction < returnType (TArgs ...)> f) \t { \t \t mListOfFunctions.push_back (f); \t} –

+0

Pourquoi faites-vous cela? Pourquoi n'utilisez-vous pas le code tel que je l'ai posté? –

+0

Je l'ai fait aussi: template délégué de classe { privé: public: \t typename std :: vector > mListOfFunctions; \t Bind void (std :: fonction f) \t {\t \t mListOfFunctions.push_back (f); \t} modèle \t \t vide Invoke (TArgs && ... arg) { \t \t \t pour (auto f: mListOfFunctions) \t \t { \t \t \t f (std :: transmettre (arg) ...); \t \t} \t} }; mais quand j'appelle Bind il renvoie à nouveau cette erreur –