2009-11-19 3 views
3

En C++, est-il possible de définir un ordre de tri pour les pointeurs vers les fonctions membres? Il semble que l'opérateur < est indéfini. En outre, il est illégal de lancer pour annuler *.C++ comparaison de pointeurs de fonction membres

class A 
{ 
    public: 
     void Test1(){} 
     void Test2(){} 
}; 

int main() 
{ 
    void (A::* const one)() = &A::Test1; 
    void (A::* const two)() = &A::Test2; 

    bool equal = one == two; //Equality works fine. 
    bool less = one < two; //Less than doesn't. 

    return 0; 
} 

Merci!

+0

Qu'essayez-vous d'accomplir? –

+0

J'aimerais pouvoir stocker ces pointeurs dans des ensembles ou des cartes. Ils exigent tous deux qu'un ordre de tri soit défini. – Imbue

+0

Comment dangereux ferait memcmp ((void *) & un, (void *) & two, sizeof (un)); être? – Imbue

Répondre

5

Les pointeurs de fonction ne sont pas comparables sur le plan relationnel en C++. Les comparaisons d'égalité sont prises en charge, sauf dans les cas où au moins l'un des pointeurs pointe vers une fonction membre virtuelle (auquel cas le résultat n'est pas spécifié).

Bien sûr, vous pouvez toujours introduire un ordre en implémentant un prédicat de comparaison et en comparant explicitement les pointeurs (cela ne sera pas trop élégant, car vous ne pouvez utiliser que des comparaisons d'égalité). D'autres solutions possibles traverseraient le territoire des différents «hacks» de mise en œuvre.

+0

Donc, c'est impossible et n'a pas de solution de contournement? – Imbue

+0

Le travail autour est comme je l'ai suggéré, qui consiste à implémenter le pointeur de fonction membre en tant que foncteur. – jmucchiello

+0

@villapx: Tout d'abord, votre texte souligné parle spécifiquement des pointeurs vers les membres ** data **. Deuxièmement, votre texte souligné parle spécifiquement des pointeurs ** réguliers **, pas des pointeurs de type pointeur-à-membre. Donc non, ce n'est même pas proche de la situation du PO. – AnT

2

Les pointeurs de fonction membre ne sont pas des pointeurs réels. Vous devriez les regarder comme des structures opaques. Qu'est-ce qu'un pointeur de méthode contient:

struct method_pointer { 
    bool method_is_virtual; 
    union { 
     unsigned vtable_offset; // for a virtual function, need the vtable entry 
     void* function_pointer; // otherwise need the pointer to the concrete method 
    } 
}; 

Si vous pouviez jeter cela void * (vous ne pouvez pas) tout ce que vous auriez est un pointeur du struct, pas un pointeur sur le code. C'est pourquoi l'opérateur <() est également indéfini puisque la valeur du pointeur de la structure est exactement là où elle se trouve en mémoire.

En plus de cela, de quoi faites-vous le tri?

+0

Alors qu'il est vrai que le physique général La structure d'un pointeur membre est différente de la structure d'un pointeur ordinaire (non-membre), la raison de cela a absolument rien à voir avec les pointeurs "self". En C++, les pointeurs vers les membres ne sont en aucun cas attachés à des «moi» concrets. Ce que vous décrivez ci-dessus ressemble à une implémentation de "fermeture", mais C++ n'a pas de fermeture. – AnT

+0

J'ai réécrit ma réponse. Je ne sais pas ce que je pensais. – jmucchiello

+0

jmucchiello, Un pointeur de méthode ne contient aucun pointeur sur un objet instancié de quelque sorte que ce soit.Un pointeur de méthode est un pointeur sur le code, pas un objet/struct ou tout autre chose que vous voulez appeler. – Imbue

Questions connexes