Использование нестатического члена класса внутри функции сравнения
Вопрос
В настоящее время я разрабатываю класс синтаксического анализатора, которому в какой-то момент кода необходимо сортировать структуры, содержащие информацию об операторах.Каждый оператор имеет приоритет, который определяется пользователем с помощью открытых функций-членов моего класса 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)));