2

我目前正在开发一个语法分析器类,该类需要在代码的某个点对包含运算符信息的结构进行排序。每个运算符都有一个优先级,这是用户通过我的分析器类的公共成员函数定义的。因此,在排序时,我需要我的排序函数根据相应运算符的优先级对元素进行排序。我正在使用以下代码来比较元素:

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 函数比较了 type 的元素op_char,然后我从包含 type 元素的 map 中检索 operator def ,这些元素op_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 函数?显然该功能应该是非静态的,但如果我不使其成为静态,我将无法使用它......

4

3 回答 3

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上查看更多示例

于 2009-11-13T19:40:11.260 回答
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));
于 2009-11-13T19:55:12.650 回答
3

如果您希望 op_comp 是非静态的,您可以使用 Boost.Lambda 或 Boost.Bind:

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
于 2009-11-13T20:08:15.527 回答