在比较函数中使用非静态类成员

问题描述 投票:2回答:3

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

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,我从一个包含类型为 op_def,其中有一个字段 "优先级"。

我面临的问题是,我无法使用 std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp)) (其中OPS是一个 vector of op_info) 方法。我得到了以下错误,这听起来很符合逻辑。

错误:在静态成员函数中无效使用成员`parser::operators'。

我的问题是:我怎样才能强迫 std::sort 使用一个编译函数,使用类中非静态成员的元素?很明显,这个函数应该是非静态的,但是如果我不把它变成静态的,我就无法使用它。

c++ class static sorting functor
3个回答
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));

Where my_parser 是你正在使用的解析器实例。或者,如果你正在调用 std::sort 的解析器中,你可以简单地写。

std::sort(ops.begin(), ops.end(), op_comp(this));

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


3
投票

如果你想让 op_comp 成为非静态的,你可以使用 Boost.Lambda 或 Boost.Bind。

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
© www.soinside.com 2019 - 2024. All rights reserved.