Использование нестатического члена класса внутри функции сравнения - PullRequest
1 голос
/ 13 ноября 2009

В настоящее время я разрабатываю класс синтаксического анализатора, которому необходимо в точке кода сортировать структуры, содержащие информацию об операторах. Каждый оператор имеет приоритет, который определяется пользователем через публичные функции-члены моего класса анализатора. Таким образом, при сортировке мне нужна моя функция сортировки, чтобы упорядочивать элементы на основе приоритета соответствующего оператора. Я использую следующий код для сравнения элементов:

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

Обратите внимание, что я должен был сделать эту функцию статической, поскольку она определена внутри класса.

Фактически, моя функция сравнения сравнивает элементы типа op_char, и я извлекаю оператор def из карты, которая содержит элементы типа op_def, которые имеют поле "приоритет".

Проблема, с которой я сталкиваюсь, заключается в том, что мне не удается использовать std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp)) (где ops - это метод vector of op_info). Я получаю следующую ошибку, которая звучит вполне логично:

ошибка: недопустимое использование члена `parser :: operator 'в статической функции-члене

Вот мой вопрос: как я могу заставить std :: sort использовать функцию comp, которая использует элементы из нестатических членов класса? Очевидно, что функция должна быть нестатичной, но мне не удастся использовать ее, если я не сделаю ее статичной ...

Заранее спасибо за помощь, CFP.

Ответы [ 3 ]

5 голосов
/ 13 ноября 2009

Сделайте операторы статичными, и вы сможете использовать их в op_comp.

В качестве альтернативы, используйте функтор вместо функции:

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) 

См. Больше примеров на cplusplus.com

3 голосов
/ 13 ноября 2009

Если вы хотите, чтобы op_comp был нестатичным, вы можете использовать Boost.Lambda или Boost.Bind:

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
3 голосов
/ 13 ноября 2009

Используйте функтор вместо функции:

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

Таким образом, метод op_comp может оставаться нестатичным. Однако вызывающей стороне необходим экземпляр синтаксического анализатора, где хранятся все операторы. Это использование нашего нового функтора:

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

Где my_parser - это экземпляр анализатора, который вы используете. Кроме того, если вы звоните std::sort из анализатора, вы можете просто написать:

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