2009-11-13 2 views
1

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

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

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

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

Отлично! Это действительно работает очень хорошо. –

5

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

+1

Спасибо вы! Однако моя проблема заключается в том, что содержимое «операторов» зависит от того, в каком экземпляре «парсер» я имею дело. Другим решением, я понял, было также просто копировать информацию о приоритете каждому объекту op_info при создании такого объекта. Я очень впечатлен тем, насколько быстрыми и хорошими являются ответы и насколько хорошими являются люди на этом веб-сайте. Спасибо! –

+0

это очень приятное решение! Спасибо –

3

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

parser my_parser; 
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser))); 
+0

+1. Используйте TR1 'std :: tr1 :: bind', если доступно; иначе 'boost :: bind'. –

Смежные вопросы