我目前正在开发一个语法分析器类,在代码的某个点上,需要对包含运算符信息的结构进行排序。每个运算符都有一个优先级,用户通过我的分析器类的公共成员函数定义。因此,在排序时,我需要我的排序功能来根据相应运算符的优先级对元素进行排序。我正在使用以下代码来比较元素:
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;
}
请注意,我必须将此函数设为静态,因为它是在类中定义的。
实际上,我的compare函数比较了op_char
类型的元素,并从包含类型为op_def
的元素的映射中检索运算符def,其中包含字段“priority”。
我遇到的问题是我无法使用std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp))
(其中ops是vector of op_info)
方法。我收到以下错误,这听起来很合乎逻辑:
错误:在静态成员函数
中无效使用成员`parser :: operators'这是我的问题:如何强制std :: sort使用comp函数,该函数使用来自类的非静态成员的元素?显然这个函数应该是非静态的,但是如果我不使它静态的话,我就无法使用它...
先谢谢你的帮助, CFP。
答案 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)
上查看更多示例
答案 1 :(得分: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));
答案 2 :(得分:3)
如果您希望op_comp是非静态的,可以使用Boost.Lambda或Boost.Bind:
parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));