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.

Était-ce utile?

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));

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)));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top