L'utilisation d'un membre de la classe non statique dans une fonction de comparaison
Question
Je développe actuellement une classe d'analyseur syntaxique qui a besoin, à un point du code, pour trier struct conservant les informations sur les opérateurs. Chaque opérateur a une priorité, ce qui est défini par l'utilisateur grâce à des fonctions membres publiques de ma classe de l'analyseur. Ainsi, lorsque le tri, je besoin de ma fonction de tri pour commander des éléments en fonction de la priorité de l'opérateur correspondant. J'utilise le code suivant pour comparer les éléments:
bool parser::op_comp(const op_info& o1, const op_info& o2) {
op_def& op1 = operators[o1.op_char];
op_def& op2 = operators[o2.op_char];
return op1.priority > op2.priority;
}
Notez que je devais faire cette fonction statique, car il est défini à l'intérieur d'une classe.
En fait, ma fonction de comparaison compare les éléments de type op_char
, et je récupérer la définition de l'opérateur à partir d'une carte qui contient des éléments de type op_def
, qui ont un champ « priorité ».
Le problème que je suis face est que je ne parviens pas à utiliser std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp))
(où ops est une méthode de vector of op_info)
je reçois l'erreur suivante, qui semble tout à fait logique:.
erreur: utilisation non valide de membre `analyseur :: opérateurs en fonction membre statique
Voici ma question: comment puis-je forcer std :: sort d'utiliser une fonction de comp qui utilise des éléments des membres non statiques de la classe? Il est évident que la fonction doit être non-statique, mais je ne peux pas gérer l'utiliser si je ne le fais pas statique ...
Merci d'avance pour votre aide, CFP.
La solution
Utilisez un foncteur au lieu d'une fonction:
struct op_comp : std::binary_function<op_info, op_info, bool>
{
op_comp(parser * p) : _parser(p) {}
bool operator() (const op_info& o1, const op_info& o2) {
return _parser->op_comp(o1, o2);
}
parser * _parser;
};
De cette façon, la méthode op_comp
peut rester non statique. Cependant, l'appelant a besoin d'une instance de l'analyseur, où sont tous les opérateurs sont stockés. Ceci est l'utilisation de notre nouveau foncteur:
std::sort(ops.begin(), ops.end(), op_comp(&my_parser));
Où my_parser
est l'instance de l'analyseur que vous utilisez. Sinon, si vous appelez std::sort
de l'analyseur, vous pouvez simplement écrire:
std::sort(ops.begin(), ops.end(), op_comp(this));
Autres conseils
Assurez-opérateurs statiques aussi bien, et vous serez en mesure de l'utiliser dans op_comp.
En variante, utiliser un foncteur au lieu d'une fonction:
class myCompareClass {
public:
bool operator() (
const op_info& o1, const op_info& o2) {
op_def& op1 = operators[o1.op_char];
op_def& op2 = operators[o2.op_char];
return op1.priority > op2.priority;
}
private:
... operators ...
} myCompareObject;
std::sort(ops.begin(), ops.end(), myCompareObject)
Voir d'autres exemples à cplusplus.com
Si vous voulez op_comp être vous non statique pouvez utiliser Boost.Lambda ou Boost.Bind:
parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));