根据非静态值对结构进行排序(C ++)

时间:2015-02-10 15:03:42

标签: c++ sorting std

我有一个EnemyRhombus课程。它是一个单位,可以移动到地图上的不同点。

我希望按照与它们的距离增加的顺序处理它可以移动的点。

要做到这一点,我想对点进行排序。

代码1:

class EnemyRhombus
{
public:
    int x,y;
    int dist(Point p)
    {
        int dx=abs(p.x-x);
        int dy=abs(p.y-y);
        return dx+dy-min(dx,dy);
    }
    bool points_cmp(Point f, Point s)
    {
        return dist(f)<dist(s);
    }
    void move()
    {
        vector<Point> candidates;
        //...
        sort(candidates.begin(),candidates.end(),points_cmp);
    }
}

无法编译。打印

[错误]没有匹配函数来调用'sort(std :: vector :: iterator,std :: vector :: iterator,&lt; unresolved overloaded function type&gt;)'

代码2:

class EnemyRhombus
{
public:
    int x,y;
    static int dist(Point p, int tx, int ty)
    {
        int dx=abs(p.x-tx);
        int dy=abs(p.y-ty);
        return dx+dy-min(dx,dy);
    }
    template<int X, int Y> static bool points_cmp(Point f, Point s) 
    {
        return dist(f,X,Y)<dist(s,X,Y);
    }
    void move()
    {
        vector<Point> candidates;
        //...
        sort(candidates.begin(),candidates.end(),points_cmp<x,y>);
    }
}

产生错误:

[错误]'EnemyRhombus :: x'不能出现在常量表达式

[错误]'EnemyRhombus :: y'不能出现在常量表达式


我该如何解决这个问题?


使用答案中的示例可能会产生错误和警告,说默认情况下启用了c ++ 11,但事实并非如此(至少在orwell dev-cpp中)。 要使它们工作,应该将-std=c++11添加到编译器命令。 (工具 - &gt;编译器选项 - &gt;在我的情况下是Genera)

4 个答案:

答案 0 :(得分:2)

std::sort无法使用points_cmp,因为它没有this指针,因为您正在尝试将指针传递给成员函数,所以

如果您的编译器支持C ++ 11,您可以使用:

std::sort( candidates.begin(),
           candidates.end(),
           bind(&EnemyRhombus::points_cmp, this, _1, _2));

或者让函数static或免费函数出类

答案 1 :(得分:2)

除了使用静态/类外函数或使用P0W建议的方法之外,您还可以使用C ++ 11 lambda。

std::sort(candidates.begin(),candidates.end(),
    [&](Point f, Point s) { return dist(f) < dist(s); }
);

lambda负责排序的顺序。

答案 2 :(得分:2)

在代码1的情况下,c ++ 14可以做得更好:

std::sort(candidates.begin(), candidates.end(), [this] (auto a, auto b) {
  return points_cmp(a, b);
});

答案 3 :(得分:1)

您可以考虑使用 lambda 以自定义方式对vector<Point>进行排序;可以在lambda的主体中指定自定义排序顺序(注意lambda从C ++ 11开始可用):

void move()
{
    std::vector<Point> candidates;
    //...

    //
    // Specify your custom sorting using a lambda:
    // 
    std::sort(candidates.begin(), candidates.end(), [this](Point f, Point s) {
        return dist(f) < dist(s);
    });
}

另请注意,在lambda中,您必须使用 [this] capture 语法,因为您正在调用dist()非静态成员函数在lambda的身体内。


此外,如果您的Point课程 不便于复制,请考虑使用const&传递它(以避免无用的&#34;深层副本&# 34; ):

std::sort(candidates.begin(), 
          candidates.end(), 
          [this](const Point& f, const Point& s) {
              return dist(f) < dist(s);
          }
);