2010-12-06 4 views
25

Comment puis-je obtenir un pointeur de méthode pour une surcharge particulière d'une méthode:C++ pointeur de méthode surchargée

struct A { 
    void f(); 
    void f(int); 
    void g(); 
}; 

Je sais que

&A::g 

est un pointeur vers g. Mais comment puis-je obtenir un pointeur vers f ou f(int)?

Répondre

32
(void (A::*)()) &A::f 
(void (A::*)(int)) &A::f 

pointeurs de fonction et des pointeurs de fonction membres ont cette fonction - la surcharge peut être résolu en ce que le résultat a été affecté ou coulée.

Si les fonctions sont statiques, alors vous devez les traiter comme des fonctions:

(void (*)()) &A::f; 
(void (*)(int)) &A::f; 

ou même

(void (*)()) A::f; 
(void (*)(int)) A::f; 
+0

Merci! Que faire si les fonctions membres sont statiques? (Je reçois 'erreur: adresse de la fonction surchargée sans information de type contextuel') –

+0

@Neil: Voir mon edit –

+0

Oh, je vois, je viens de me débarrasser du premier' A :: 'pour les fonctions statiques, car ils peuvent être jeté aux pointeurs réguliers. Vous me battez aussi :) –

9

Il vous suffit de jeter le résultat de &A::f afin d'éliminer l'ambiguïté :

static_cast<void (A::*)()>(&A::f); // pointer to parameterless f 
static_cast<void (A::*)(int)>(&A::f); // pointer to f which takes an int 
+0

Imho c'est l'un des plus grands messages postés au SE sur le C++ ... – peterh

5

Merci à Stefan Pabst pour l'idée suivante, wh Il l'a présenté lors d'une conférence de cinq minutes à ACCU 2015. Je l'ai étendu avec des types de balises pour permettre de résoudre les surcharges par leur qualificatif cv et/ou leur qualificatif de référence, et un template variable C++ 17 pour éviter d'avoir à taper de parenthèses qui est autrement nécessaire.

Cette solution fonctionne sur le même principe que les réponses cast, mais vous évitez d'avoir à redéfinir le type de retour de la fonction ou, dans le cas de fonctions membres, le nom de la classe dont la fonction est une membre de, comme le compilateur est capable de déduire ces choses.

bool free_func(int, int) { return 42; } 
char free_func(int, float) { return true; } 
struct foo { 
    void mem_func(int) {} 
    void mem_func(int) const {} 
    void mem_func(long double) const {} 
}; 

int main() { 
    auto f1 = underload<int, float>(free_func); 
    auto f2 = underload<long double>(&foo::mem_func); 
    auto f3 = underload<cv_none, int>(&foo::mem_func); 
    auto f4 = underload<cv_const, int>(&foo::mem_func); 
} 

Le code mise en œuvre du modèle underload est here.

Questions connexes