简体   繁体   English

C ++ std :: sort with Class中的谓词函数

[英]C++ std::sort with predicate function in Class

I want to sort vector of certain struct with certain order in certain class. 我想在某个类中按某种顺序对某个结构的向量进行排序。 I've wrote definition of struct and predicate function in a class and run std::sort in a method of the class with these struct and function. 我在类中编写了struct和predicate函数的定义,并在具有这些struct和function的类的方法中运行std :: sort。 But compilation error has occurred. 但是发生了编译错误。 gcc version is 4.0.1 and OS is Mac OSX. gcc版本是4.0.1,OS是Mac OSX。 The code is following: 代码如下:

class sample {
public:
  struct s {
    int x;
    int y;
  };

  bool cmp (struct s a, struct s b) {
    if (a.x == b.x)
      return a.y < b.y;
    else
      return a.x < b.x;
  }

  int func(void) {
    std::vector <struct s> vec;

    // ...

    sort(vec.begin(), vec.end(), cmp);  // compilation error

    // ...

    return 0;
  }
};

int main(void) {
  sample *smp = new sample();
  smp->func();
  return 0;
}

Error message was huge and complex. 错误消息庞大而复杂。 So this is first two lines of it. 所以这是前两行。

sortSample.cpp: In member function 'int sample::func()': sortSample.cpp:在成员函数'int sample :: func()'中:
sortSample.cpp:51: error: argument of type 'bool (sample::)(sample::s, sample::s)' does not match 'bool (sample::*)(sample::s, sample::s)' sortSample.cpp:51:error:类型'bool(sample ::)(sample :: s,sample :: s)'的参数与'bool(sample :: *)不匹配(sample :: s,sample :: S)”
... ...

Instead of above approach, the code could run correctly with following ways. 代替上述方法,代码可以通过以下方式正确运行。

  1. Define struct s and function cmp() outside of class sample . class sample之外定义struct s和function cmp()
  2. Remove function cmp() and define operator overloading of < in struct s . 删除函数cmp()并定义< in struct s运算符重载。

Sample code of each approach is bellow. 每种方法的示例代码如下。

1) 1)

struct s {
  int x;
  int y;
};

bool cmp (struct s a, struct s b) {
  if (a.x == b.x)
    return a.y < b.y;
  else
    return a.x < b.x;
}

class sample {
// ...

2) 2)

struct s {
  int x;
  int y;

  bool operator<(const struct s & a) const {
    if (x == a.x)
      return y < a.y;
    else
      return x < a.x;
  }
};

Can anyone tell a mechanism of this behavior? 任何人都可以告诉这种行为的机制吗? Why does first approach invokes compilation error? 为什么第一种方法会调用编译错误?

Thanks. 谢谢。

In the first case cmp is declared as a member function of the class sample and hence requires this pointer for calling it. 在第一种情况下, cmp被声明为class sample的成员函数,因此需要this指针来调用它。 Since the this pointer is not available compiler is complaining about it. 由于this指针不可用,编译器正在抱怨它。 You can make it work by declaring cmp as static function since static functions do not require this pointer for calling. 您可以通过将cmp声明为static函数来使其工作,因为静态函数不需要此指针进行调用。 In the second case, since cmp is declared as a stand-alone function again it will behave same as static function. 在第二种情况下,由于cmp再次被声明为独立函数,因此它的行为与静态函数相同。 In the third case (with overloaded operator), the sort algorithm will take care of calling the function for each object in the vector and hence it compiles. 在第三种情况下(使用重载运算符),排序算法将负责为向量中的每个对象调用函数,从而进行编译。

由于cmp与任何特定的样本实例无关,因此将其设为静态成员函数。

The third approach which can be listed in your possibilities is using operator(): 可以在您的可能性中列出的第三种方法是使用operator():

bool operator() (const s& a, const s& b) const
{
    if (a.x == b.x)
        return a.y < b.y;
    else
        return a.x < b.x;
}

sort(vec.begin(), vec.end(), *this);

I think defining cmp outside the class is best, because you should only make a function a member function when you need it to access some private feature in the class, and logically it feels right for it to be there. 我认为在类之外定义cmp是最好的,因为当你需要它来访问类中的一些私有特性时,你应该只将一个函数作为一个成员函数,从逻辑上讲,它在那里是合适的。 cmp is just a utility function that provides your class sample with functionality for its implementation, but it doesn't actually need to access private members. cmp只是一个实用程序函数,它为您的类sample提供了实现的功能,但实际上并不需要访问私有成员。 Furthermore, it's probably not going to be invoked in the context of an object (its only operations work on its parameters; nothing on the this pointer), nor must it be invoked in the context of a class sample::cmp . 此外,它可能不会在对象的上下文中调用(它的唯一操作在其参数上工作;在this指针上没有任何内容),也不能在类sample::cmp的上下文中调用它。 While it may seem like a trivial point, giving functions or code in general unnecessary breadth of access can be the start of the source of many a software bug or design convolution. 虽然看起来似乎是一个微不足道的观点,但通常给予函数或代码不必要的访问宽度可能是许多软件错误或设计卷积的来源的开始。

The added benefit of doing the above is that your invocation of std::sort will work, which answers your question. 执行上述操作的额外好处是,您对std::sort调用将起作用,这可以回答您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM