Использование нестатического члена класса внутри функции сравнения

StackOverflow https://stackoverflow.com/questions/1731404

Вопрос

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

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::operators' в статической функции-члене

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

Заранее благодарю за вашу помощь, CFP.

Это было полезно?

Решение

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

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

Другие советы

Сделайте операторы также статическими, и вы сможете использовать их в 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

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

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top