Pour une classe, je souhaite stocker des pointeurs de fonction vers des fonctions membres de la même classe dans un objet de map
stockage std::function
. Mais j'échoue dès le début avec ce code:
class Foo {
public:
void doSomething() {}
void bindFunction() {
// ERROR
std::function<void(void)> f = &Foo::doSomething;
}
};
Je reçois error C2064: term does not evaluate to a function taking 0 arguments
en xxcallobj
combinaison avec des erreurs d'instanciation de modèle étranges. Actuellement, je travaille sur Windows 8 avec Visual Studio 2010/2011 et sur Win 7 avec VS10, cela échoue également. L'erreur doit être basée sur des règles C ++ étranges que je ne suis pas
std::function
, avec un supplémentthis
comme premier paramètre, commestd::function<void(Foo*, int, int)> = &Foo::doSomethingArgs
Soit vous avez besoin
afin que vous puissiez l'appeler sur n'importe quelle instance, ou vous devez lier une instance spécifique, par exemple
this
la source
this
?Si vous avez besoin de stocker une fonction membre sans l'instance de classe, vous pouvez faire quelque chose comme ceci:
À quoi ressemblerait le type de stockage sans auto ? Quelque chose comme ça:
Vous pouvez également transmettre ce stockage de fonction à une liaison de fonction standard
Notes passées et futures: Une ancienne interface std :: mem_func existait, mais est depuis obsolète. Une proposition existe, post C ++ 17, pour rendre le pointeur vers les fonctions membres appelables . Ce serait le bienvenu.
la source
std::mem_fn
n'a pas été supprimé; un tas de surcharges inutiles étaient. D'autre part, ilstd::mem_fun
est obsolète avec C ++ 11 et sera supprimé avec C ++ 17.template<class R, class T> unspecified mem_fn(R T::*);
et elle ne disparaîtra pas.Malheureusement, C ++ ne vous permet pas d'obtenir directement un objet appelable faisant référence à un objet et à l'une de ses fonctions membres.
&Foo::doSomething
vous donne un "pointeur vers la fonction membre" qui fait référence à la fonction membre mais pas à l'objet associé.Il existe deux façons de contourner ce problème, l'une consiste à
std::bind
lier le «pointeur vers la fonction membre» authis
pointeur. L'autre consiste à utiliser un lambda qui capture lethis
pointeur et appelle la fonction membre.Je préférerais ce dernier.
Avec g ++ au moins lier une fonction membre à ceci se traduira par un objet à trois pointeurs de taille, l'assigner à un
std::function
entraînera une allocation de mémoire dynamique.D'un autre côté, un lambda qui capture
this
n'a qu'un seul pointeur en taille, l'assigner à unstd::function
ne résultera pas en une allocation de mémoire dynamique avec g ++.Bien que je ne l'ai pas vérifié avec d'autres compilateurs, je soupçonne que des résultats similaires y seront trouvés.
la source
Vous pouvez utiliser des foncteurs si vous souhaitez un contrôle moins générique et plus précis sous le capot. Exemple avec mon api win32 pour transférer un message api d'une classe vers une autre classe.
IListener.h
Auditeur.h
Dispatcher.h
Principes d'utilisation
Bonne chance et merci à tous pour le partage des connaissances.
la source
Vous pouvez éviter de
std::bind
faire ceci:la source