Comment puis-je passer d'une fonction membre où une fonction libre est prévu?
La question est la suivante: considérer ce morceau de code:
#include <iostream>
class aClass
{
public:
void aTest(int a, int b)
{
printf("%d + %d = %d", a, b, a + b);
}
};
void function1(void (*function)(int, int))
{
function(1, 1);
}
void test(int a,int b)
{
printf("%d - %d = %d", a , b , a - b);
}
int main (int argc, const char* argv[])
{
aClass a();
function1(&test);
function1(&aClass::aTest); //<-- How should I point to a's aClass::test function?
return 0;
}
Comment puis-je utiliser le a
's aClass::test
comme un argument de function1
? Je suis coincé dans faisant cela.
Je voudrais accéder à un membre de la classe.
- Jetez un oeil à cette réponse stackoverflow.com/questions/2402579/... et aussi ce C++ FAQ parashift.com/c++-faq/pointers-to-members.html
- Ce n'est absolument pas un doublon (au moins pas de question en particulier qui est lié). Cette question est sur la façon de déclarer un membre qui est un pointeur vers une fonction; c'est sur la façon de passer un pointeur à un non-membre statique de la fonction en tant que paramètre.
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas quelque chose de mal avec l'aide de pointeurs de fonction. Cependant, des pointeurs vers des non-fonctions membres statiques ne sont pas comme les pointeurs de fonction: les fonctions doivent être appelées sur un objet qui est passé comme un implicite argument de la fonction. La signature de votre membre de la fonction ci-dessus est donc
plutôt que le type que vous essayez d'utiliser
Une approche pourrait consister à faire de la fonction de membre de
static
dans ce cas elle n'a pas besoin d'objet pour être appelé et vous pouvez l'utiliser avec le typevoid (*)(int, int)
.Si vous avez besoin d'accéder à tout non-membre statique de votre classe et vous avez besoin de coller avec des pointeurs de fonction, par exemple, parce que la fonction est une partie d'une interface C, votre meilleure option est de toujours passer un
void*
à votre fonction prenant des pointeurs de fonction et appelez votre membre par le biais d'une fonction de transmission qui obtient un objet à partir de lavoid*
, puis appelle la fonction membre.Dans une bonne interface C++, vous pouvez avoir un coup d'oeil à avoir votre prise de fonction de type "modèle" argument de la fonction des objets à usage arbitraire types de classe. Si vous utilisez basé sur un modèle d'interface n'est pas souhaitable que vous devriez utiliser quelque chose comme
std::function<void(int, int)>
: vous pouvez créer un convenablement appelable de la fonction de l'objet pour ces, par exemple, à l'aide destd::bind()
.Le type-safe approches à l'aide d'un argument de modèle pour le type de classe ou un
std::function<...>
est préférable que l'utilisation d'unevoid*
interface, car ils suppriment le potentiel pour des erreurs dues à une fonte de type incorrect.De clarifier comment utiliser un pointeur de fonction à appeler une fonction membre, voici un exemple:
void*
, ce qui signifie que vous pouvez obtenir de très méchants bugs, car il n'est pas tapé vérifié plus.void*
solution C) suggère avec "votre meilleure option est de toujours passer un void* à votre fonction" etstatic_cast<foo*>(context)->member(i0, i1);
c'est la seule solution et qu'il est sécuritaire, ce qui n'est pas, Nous le savons tous les problèmes causés par un travail autour du type de système, et de votre réponse à mon humble avis encourage cette utilisation abusive.template <typename Fun> void f(Fun fun /*...*/)
et dans la mise en œuvre def()
utiliser lefun
objet adapté à l'aide (par exemplestd::bind()
et appeler la fonction via l'aide avec les arguments.@Pete Becker réponse est bien, mais vous pouvez aussi le faire sans passer le
class
instance comme un paramètre explicite àfunction1
en C++ 11:void function1(std::function<void(int, int)>)
correct?void function1(std::function<void(int, int)> functionToCall)
et puisfunctionToCall(1,1);
. J'ai essayé de modifier la réponse, mais quelqu'un l'a rejetée comme ne faisant aucun sens pour une raison quelconque. Nous allons voir s'il obtient upvoted à un certain point.Un pointeur de fonction membre est différente à partir d'un pointeur de fonction. Pour utiliser une fonction membre par l'intermédiaire d'un pointeur vous avez besoin d'un pointeur (évidemment ) et un objet de l'appliquer à. Donc la version appropriée de
function1
seraitet de l'appeler:
function
dansvoid (aClass::*function)(int, int)
était un type, parce que c'est un type danstypedef void (aClass::*function)(int, int)
.int X;
crée un objet.Depuis 2011, si vous pouvez changer
function1
, le faire, comme ceci:(démonstration en direct)
Remarquez aussi que j'ai corrigé votre cassé définition de l'objet (
aClass a();
déclare une fonction).J'ai posé une question similaire ( C++ openframeworks passant nulle à partir d'autres classes ), mais la réponse que j'ai trouvé était plus clair voici donc l'explication pour les futurs enregistrements:
il est plus facile d'utiliser std::function, comme dans:
et ensuite appeler comme:
ou encore plus simple:
où vous créez un lambda qui appelle l'objet de la capture par référence
Vous pouvez arrêter de frapper votre tête maintenant. Voici le wrapper pour la fonction de membre de soutien existant fonctions dans la plaine C des fonctions comme arguments.
thread_local
directive est la clé ici.http://cpp.sh/9jhk3
Commenter des problèmes avec cette approche.
Autres réponses ne parviennent pas à appeler existant plaine
C
fonctions: http://cpp.sh/8exunC
des fonctions comme arguments.J'ai fait la fonction membre statique et tous les travaux: