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) alors je veux faire comme ce qui suit pour chaque surcharge Méthodes dans GAPP: P> appeler ceci pour Cela me donnera p> Erreur de syntaxe: «Double» doit être précédée de ')' P>
blockQuote> 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? P> p> foo () code> est ok, mais comment puis-je appeler ceci pour foo (double d) code>? Pourquoi les suivants ne sont-ils pas suivis? p>
6 Réponses :
Vous pouvez essayer explicitement le pointeur, pour le faire savoir lequel choisir, comme celui-ci: Disclaimer: Je n'ai pas testé P> P> P>
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)
Ceci fonctionne,
typedef void (GApp::*MemberFunctionType)(double);
MemberFunctionType pointer = &GApp::foo;
connect(MemberFunctionType);
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.
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
}
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.
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;
}
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.
Mon code d'origine est comme celui-ci,
connecteurs .... p> signaux ... p> finaly, connexion ... p> 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. : ( p> p>
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: p> blockQuote>
xxx pré> 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: p>
xxx pré> devient: p>
xxx pré> ne jamais appeler variables
TMP code>; -) p>Je suppose que le casting de Newacct est également en sécurité, car exactement la même raison. Casting à
Void (Gapp :: *) (Double) Code> est défini comme étant identique à l'initialisation d'un type temporaire de typeVoid (gapp :: *) (double) code>. Étant donné que l'expression utilisée pour initialiser est& gapp: FOO code>, 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. P>Donc, si vous préférez une doublure: p>
xxx pré> 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é. P> p>
Et ils disent que C ++ est difficile à comprendre! ;-)
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 ......