根据非静态值对结构进行排序 (C++)
Sort structs depending on non-static value (C++)
我有一个 EnemyRhombus
class。它是一个单位,可以移动到地图上的不同点。
我想处理它可以移动到的点,按照与它们的距离增加的顺序。
为此,我想对这些点进行排序。
代码 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, < unresolved overloaded function type>)'
代码 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
添加到编译器命令中。
(在我的例子中,工具->编译器选项-> Genera)
std::sort
不能使用 points_cmp
因为它没有 this
指针,因为您正试图将指针传递给成员函数,所以
如果你的编译器支持C++11,你可以使用:
std::sort( candidates.begin(),
candidates.end(),
bind(&EnemyRhombus::points_cmp, this, _1, _2));
否则创建函数 static
或 class
中的自由函数
除了使用 static/out-of-class 函数或使用 P0W 建议的方法外,您还可以使用 C++11 lambda。
std::sort(candidates.begin(),candidates.end(),
[&](Point f, Point s) { return dist(f) < dist(s); }
);
lambda 负责排序的顺序。
在代码 1 的情况下,c++14 允许做得更好:
std::sort(candidates.begin(), candidates.end(), [this] (auto a, auto b) {
return points_cmp(a, b);
});
您可以考虑使用 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
class 复制起来 不 便宜,请考虑使用 const&
传递它(以避免无用的 "deep copies"):
std::sort(candidates.begin(),
candidates.end(),
[this](const Point& f, const Point& s) {
return dist(f) < dist(s);
}
);
我有一个 EnemyRhombus
class。它是一个单位,可以移动到地图上的不同点。
我想处理它可以移动到的点,按照与它们的距离增加的顺序。
为此,我想对这些点进行排序。
代码 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, < unresolved overloaded function type>)'
代码 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
添加到编译器命令中。
(在我的例子中,工具->编译器选项-> Genera)
std::sort
不能使用 points_cmp
因为它没有 this
指针,因为您正试图将指针传递给成员函数,所以
如果你的编译器支持C++11,你可以使用:
std::sort( candidates.begin(),
candidates.end(),
bind(&EnemyRhombus::points_cmp, this, _1, _2));
否则创建函数 static
或 class
除了使用 static/out-of-class 函数或使用 P0W 建议的方法外,您还可以使用 C++11 lambda。
std::sort(candidates.begin(),candidates.end(),
[&](Point f, Point s) { return dist(f) < dist(s); }
);
lambda 负责排序的顺序。
在代码 1 的情况下,c++14 允许做得更好:
std::sort(candidates.begin(), candidates.end(), [this] (auto a, auto b) {
return points_cmp(a, b);
});
您可以考虑使用 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
class 复制起来 不 便宜,请考虑使用 const&
传递它(以避免无用的 "deep copies"):
std::sort(candidates.begin(),
candidates.end(),
[this](const Point& f, const Point& s) {
return dist(f) < dist(s);
}
);