Domanda

Al momento sto sviluppando una classe analizzatore syntaxic che ha bisogno, in un punto del codice, per ordinare le strutture informazioni su operatori titolari. Ogni operatore ha una priorità, che è definito dall'utente tramite funzioni membro pubbliche della mia classe analizzatore. Così, durante l'ordinamento, ho bisogno della mia funzione di ordinamento per ordinare gli elementi in base alla priorità del relativo operatore. Sto utilizzando il seguente codice per confrontare elementi:

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

Si noti che ho dovuto fare questa funzione statica, dal momento che è definita all'interno di una classe.

In realtà, la mia funzione di confronto confronta elementi di tipo op_char, e recuperare il DEF operatore da una mappa che contengono elementi di tipo op_def, che hanno un campo "priorità".

Il problema che sto affrontando è che io non riesco a utilizzare std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp)) (dove Ops è un metodo vector of op_info) ottengo il seguente errore, che suona abbastanza logico:.

errore: Utilizzo non valido di membri `parser :: operatori in funzione di membro static

Ecco la mia domanda: come posso forzare std :: sorta di utilizzare una funzione bozzetto che fa uso di elementi provenienti da membri non statici della classe? Ovviamente la funzione dovrebbe essere non statico, ma non riesce a usarla se non faccio lo static ...

Grazie in anticipo per il vostro aiuto, PCP.

È stato utile?

Soluzione

Usa un funtore invece di una funzione:

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

In questo modo il metodo op_comp può rimanere non statico. Tuttavia il chiamante ha bisogno di un'istanza del parser, dove sono tutti gli operatori sono memorizzati. Questo è l'utilizzo del nostro nuovo funtore:

std::sort(ops.begin(), ops.end(), op_comp(&my_parser));

Dove my_parser è l'istanza di parser che si sta utilizzando. In alternativa, se si chiama std::sort dal parser, si può semplicemente scrivere:

std::sort(ops.begin(), ops.end(), op_comp(this));

Altri suggerimenti

make operatori statica pure, e sarete in grado di utilizzarlo in op_comp.

In alternativa, utilizzare un funtore invece di una funzione:

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) 

Vedere altri esempi in cplusplus.com

Se si vuole op_comp essere non statico è possibile utilizzare Boost.Lambda o Boost.Bind:

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top