6
votes

Pointeur de fonction de membre surchargé sur le modèle

J'essaie de stocker les pointeurs de la fonction membre par des modèles comme celui-ci: (Ceci est une version simplifiée de mon code réel) xxx

alors je veux faire comme ce qui suit pour chaque surcharge Méthodes dans GAPP: xxx

appeler ceci pour foo () est ok, mais comment puis-je appeler ceci pour foo (double d) ? Pourquoi les suivants ne sont-ils pas suivis? xxx

Cela me donnera

Erreur de syntaxe: «Double» doit être précédée de ')'

Je ne comprends pas la syntaxe qui doit être utilisée ici. Cela peut être une qustion stupide, mais quelqu'un peut-il m'aider à ce sujet?


2 commentaires

C'est une meilleure idée d'utiliser des fonctionneurs au lieu des pointeurs de fonction IMHO.


L'ensemble du code fait partie de la mise en œuvre d'un signal et d'un mécanisme à sous. Donc, le litre (qui a la fente) ne veut pas savoir sur le système. Donc, je ne peux pas dire à l'auditeur à faire comme ça, faites comme ça ......


6 Réponses :


1
votes

Vous pouvez essayer explicitement le pointeur, pour le faire savoir lequel choisir, comme celui-ci: XXX

Disclaimer: Je n'ai pas testé


3 commentaires

Il ne peut pas être en sécurité: une distribution est simplement une fonction sur le gapp :: FOO Pointer. Cela ne changera pas le contenu du pointeur.


J'ai une théorie que c'est sûr, voir ma réponse pour plus de détails. Je ne l'ai pas encore confirmé dans la norme, cependant, parce que j'ai une forte soupçon, la langue de la norme correspondra à Stroustrup à C ++ PL de toute façon, et c'est une question légèrement fractionnée.


Mon erreur - Apparemment, c'est le moyen de spécifier les fonctions surchargées (voir ddj.com/article/... , quelque part près de la fin)



0
votes

Ceci fonctionne,

    typedef void (GApp::*MemberFunctionType)(double); 
    MemberFunctionType pointer = &GApp::foo;


  connect(MemberFunctionType);


1 commentaires

Ma réponse explique pourquoi cela fonctionne, en se référant à STROSTRUP et à une hypothèse que ce qu'il dit sur les points de fonction s'applique également aux pointeurs de la fonction membre.



6
votes

Votre code comme écrit ne compile pas. J'ai fait des "hypothèses" sur ce que vous vouliez faire et j'ai changé le code.

Pour résumer, vous pouvez appeler la fonction correcte en spécifiant explicitement le type de paramètre de fonction: P>

template <class Arg = void>
class signal {};
signal<double> signal_double;
signal<> signal_void;

// Arg1 is deduced from signal<Arg1> and then we use it in the declaration
// of the pointer to member function
template<class T, class Arg1>
void connect ( signal<Arg1>& sig, T& obj, void (T::*f)(Arg1) ) {}

// Add special case for 'void' without any arguments
template<class T>
void connect (signal<> & sig, T& obj, void (T::*f)()) {}


void bar ()
{
  GApp myGApp;

  //Connecting foo()
  connect(signal_void, myGApp, &GApp::foo); // Matches second overload

  //Connecting foo(double)
  connect(signal_double, myGApp, &GApp::foo); // Matches first overload
}


2 commentaires

Hey! Merci pour l'effort. Désolé, j'ai oublié de dire que mon code n'est pas complet. C'est parce que j'ai supprimé la classe de modèle de signal pour simplifier le code. BTW, oui, votre méthode fonctionne bien. Je posterai mon code d'origine, pouvez-vous y regarder alors? Merci


Wohooooo .... ouais. Tu me montres le chemin. Maintenant, tous fonctionnent correctement. Merci beaucoup.



0
votes

Utilisation de boost :: Bibliothèque de fonctions ...

#include <boost/function.hpp>

template<class Arg1>
void connect(boost::function1<void, Arg1*> fn) 
{
    //Do some stuff
}

template<class Arg1>
void connect(boost::function2<void, Arg1*, double> fn) 
{
    //Do some stuff
}

class GApp
{
public:
    void foo() {}

    void foo(double d) {}
};


int main()
{
    boost::function1<void,GApp*> f1 = (void (GApp::*)(void)) &GApp::foo;
    boost::function2<void,GApp*,double> f2 = (void (GApp::*)(double)) &GApp:foo;
    connect(f1);
    connect(f2);
    return 0;
}


2 commentaires

Hey! Merci pour les ANS. N'est-ce pas votre (void (gapp :: *) (double)) & gapp: foo; Même chose que la solution de NewacCT (void (gapp :: *) (double)) & gapp :: foo. Mais Xtofl a dit que ce n'est pas sûr :(


XTOFL a mis à jour un commentaire pour dire qu'il semble être sûr. Son préférable d'utiliser des objets de fonction plutôt que d'utiliser des pointeurs de fonction, c'est tout.



0
votes

Mon code d'origine est comme celui-ci,

connecteurs .... xxx

signaux ... xxx < p> application ... xxx

finaly, connexion ... xxx

Il y a des classes de modèle pour les signaux (qui ne sont pas mentionnés ici). J'espère que c'est plus clair la situation. (ou est-ce comme précédent?). Cette deuxième connexion fonctionnera s'il n'y a pas de FOO () (seulement FOO (double)). C'est la chose que mon code me fait mal. : (


0 commentaires

5
votes

Le langage de programmation C ++, 3e, section 7.7, P159:

Vous pouvez prendre l'adresse d'une fonction surchargée en attribuant ou initialise un pointeur à fonctionner. Dans ce cas, le type de cible est utilisé pour sélectionner dans l'ensemble des fonctions surchargées. Par exemple: xxx

autant que je sache (je n'ai pas vérifié), il en va de même pour les fonctions membres. La solution est donc probablement à scinder sur deux lignes: xxx

devient: xxx

ne jamais appeler variables TMP ; -)

Je suppose que le casting de Newacct est également en sécurité, car exactement la même raison. Casting à Void (Gapp :: *) (Double) est défini comme étant identique à l'initialisation d'un type temporaire de type Void (gapp :: *) (double) . Étant donné que l'expression utilisée pour initialiser est & gapp: FOO , je m'attendrais à ce que la même magie soit appliquée à la distribution telle que s'applique à toute autre initialisation avec une fonction surchargée. STROSTRUP ne dit pas "initialiser une variable de pointeur à fonction", dit-il "initialisation d'un pointeur à fonction". Donc, cela devrait inclure des temporaires.

Donc, si vous préférez une doublure: xxx

Cependant, je suppose que la norme a la même idée de la consistance que je le fais, et je n'ai pas vérifié.


1 commentaires

Et ils disent que C ++ est difficile à comprendre! ;-)