2017-07-25 3 views
0

J'ai une classe nommée Handler qui stocke des lambdas. Ce que je veux faire est d'avoir un std::vector de std::function qui stocke tous mes événements, par exemple. Je ne peux vraiment pas comprendre pourquoi lambdas ne fonctionne pas comme je m'y attendais.Utilisation du spécificateur automatique dans std :: function et lambdas

Voici le handler.h:

class Handler 
{ 
public: 
    Handler(); 
    ~Handler(); 

    void Register(const char* outcome, std::function<auto()> lambda); 
    void Trigger(const char* outcome); 

private: 
    std::vector<int> identifier; 
    std::vector<char*> outcome; 
    std::vector<std::function<auto()>> func; 
}; 

Et handler.cpp:

Handler::Handler() 
{ 
    //ctor stuff here 
} 


Handler::~Handler() 
{ 
    this->func.clear(); 
    this->outcome.clear(); 
    this->identifier.clear(); 
    //... 
} 

void Handler::Register(const char* outcome, std::function<auto()> lambda) 
{ 
    static int identifier = 0; 
    identifier++; 
    this->outcome.push_back((char*)outcome); 
    this->identifier.push_back(identifier); 
    this->func.push_back(lambda); 
    //Sort outcome 
} 

void Handler::Trigger(const char * outcome) 
{ 
    int i; 
    for (i = 0; i < this->identifier.size(); i++) 
    { 
     if (!strcmp(outcome, this->outcome.at(i))) 
      break; 
    } 
    this->func[i](); 
} 

Cependant, si je précise lambdas dans un Handler::Register il ne me laissera pas jeter no suitable user-defined conversion from "lambda []void()->void" to "std::function<auto()> exists. Dans cet exemple, j'utilise le type de retour void mais d'autres types aussi erreur, je ne comprends pas pourquoi le modèle de std::function ne peut pas le déduire, si c'est ce qui se passe.

Handler* events = new Handler(); 

    events->Register("Up", [=]() -> void { //Error here! 
     //do stuff 
     //return something? 
    }); 

est-il une autre façon de faire, comme sans surcharger Handler::Register?

+5

Je suis étonné de voir 'std :: fonction ' compile tout – StoryTeller

+0

je ne pense que vous pouvez avoir un vecteur de std :: fonctions chacun d'eux peut-être d'un type différent. ce serait comme avoir un vecteur qui serait capable de stocker différents types d'objets. –

+0

@StoryTeller Ce n'est pas? Je n'ai pas testé du tout puisque le compilateur ne s'en souciait pas. – Primemaster

Répondre

2

auto n'est pas un type, donc std::function<auto()> n'est pas un type non plus. De la façon dont vous l'utilisez, std::function<void()> est probablement ce que vous voulez.

Il y a d'autres problèmes avec votre code, comme indiqué dans les commentaires, donc je changerais Handler à cette

class Handler 
{ 
public: 
    Handler(); 
    // default ~Handler is fine 

    void Register(std::string outcome, std::function<void()> lambda); 
    void Trigger(const std::string & outcome outcome) const; 
    void Trigger(std::size_t index) const; 

private: 
    using Outcomes = std::map<std::string, std::function<void()>/*, custom string comparator ?*/>; 
    std::vector<Outcomes::iterator> identifier; 
    Outcomes outcomes; 
}; 

void Handler::Register(std::string outcome, std::function<void()> func) 
{ 
    auto emplaced = outcomes.emplace(std::move(outcome), std::move(func)); 
    identifier.push_back(emplaced.first); 
} 

void Handler::Trigger(const std::string & outcome) const 
{ 
    outcomes.at(outcome)(); 
} 

void Handler::Trigger(std::size_t index) const 
{ 
    identifier[index]->second(); 
} 
+0

'identifier' semble superflu. et certaines références const sont manquantes. – Jarod42

+1

@ Jarod42 Je suppose que OP utilisait 'identifier' comme index d'ordre d'insertion dans le code elided – Caleth