我见过其他人的问题,但发现没有一个问题适用于我在这里想要实现的目标。
我正在尝试使用std :: sort和std::vector<Entity *>
/*Entity.h*/
class Entity
{
public:
float x,y;
};
struct compareByX{
bool operator()(const GameEntity &a, const GameEntity &b)
{
return (a.x < b.x);
}
};
/*Class EntityManager that uses Entitiy*/
typedef std::vector<Entity *> ENTITY_VECTOR; //Entity reference vector
class EntityManager: public Entity
{
private:
ENTITY_VECTOR managedEntities;
public:
void sortEntitiesX();
};
void EntityManager::sortEntitiesX()
{
/*perform sorting of the entitiesList by their X value*/
compareByX comparer;
std::sort(entityList.begin(), entityList.end(), comparer);
}
我收到了十几个错误,比如
: error: no match for call to '(compareByX) (GameEntity* const&, GameEntity* const&)'
: note: candidates are: bool compareByX::operator()(const GameEntity&, const GameEntity&)
我不确定,但ENTITY_VECTOR是std::vector<Entity *>
,我不知道在使用compareByX仿函数时是否会出现问题?
我对C ++很陌生,所以欢迎提供任何帮助。
答案 0 :(得分:3)
仿函数是一个定义operator()的类,因此可以使用与调用函数相同的语法“调用”该类的对象:
struct functor {
bool operator()(Entity const &a, Entity const &b) {
return a.x < b.x;
}
};
如果您希望将其作为Entity类的成员,则可以使用嵌套类:
class Entity {
float x;
public:
friend class byX;
class byX {
bool operator()(Entity const &a, Entity const &b) {
return a.x < b.x;
}
};
};
然后你的排序看起来像这样:
std::sort(ManagedEndities.begin(), ManagedEntities.end(), Entity::byX());
或者,如果您通常按X对实体进行排序,则可以定义运算符&lt;实体:
class Entity {
float x;
public:
bool operator<(Entity const &other) {
return x < other.x;
}
};
在这种情况下,您对sort的使用会更简单一些:
std::sort(ManagedEntities.begin(), ManagedEntities.end());
然后,将比较函数创建为Entity类的普通成员函数会导致排序调用非常难看 - 它通常需要像std :: mem_fun_ref这样的工作来执行此操作;它太丑了,我通常会避免使用真正的代码。
答案 1 :(得分:3)
第三个进来......在你编辑了问题之后,还有一个开放主题:你的比较器将const &
带到GameEntity
类。为了使用vector<GameEntity*>
的值,它应该取const GameEntity*
个参数。
答案 2 :(得分:1)
我最近确实看到了这个问题......
答案是这样的:提供给sort
的功能不应该是某事物的成员功能。含义:它应该是静态函数或自由函数。如果您将其声明为静态函数,则仍应在其前面加Entity::compareByX
以便正确命名。
如果您在类本身中定义顺序,就像aJ已经说过的那样,您可以使用函数适配器mem_fun
或mem_fun_ref
将其转换为“免费”仿函数对象。
如果你想要一个Entity
对象进行比较,你应该为sort
提供一个对象(在这种情况下称为仿函数或比较器):
struct EntityComp {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.x < b.x;
}
}
...
std::sort( v.begin(), v.end(), EntityComp() );
答案 3 :(得分:1)
我相信compareByX
应该是static
会员或湖泊here
答案 4 :(得分:1)
根据“你想要达到的目标”,我可能会做另一个猜测...你希望能够指定是通过GameEntity::x
成员还是GameEntity::y
成员来比较你的对象{1}}成员。
最简单的方法是,像您一样,为每个成员指定一个仿函数:
struct CompareX {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.x < b.x;
}
};
struct CompareY {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.y < b.y;
}
};
CompareX compx; // create a compare object
std::sort( v.begin(), v.end(), compx );
“灵活”但更麻烦的方法是创建模板仿函数:
#include <iostream>
using namespace std;
// a mockup of your class
struct GameEntity { float x, y, z; };
// just to be able to print it...
ostream& operator<<( ostream& o, const GameEntity& g ) {
return o << "(" << g.x << ", " << g.y << ", " << g.z << ")";
}
// cumbersome starts here...
typedef float (GameEntity::*membervar);
// a 'generic' float-member comparator
template< membervar m > struct CompareBy {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.*m < b.*m ;
}
};
// example code
int main() {
using namespace std;
GameEntity v[] = { {1,0,0}, {2,0,1}, {3,-1,2} };
GameEntity* vend = v + sizeof(v)/sizeof(v[0]);
sort( v, vend, CompareBy< &GameEntity::x >() );
copy( v, vend, ostream_iterator<GameEntity>( cout, "\n" ) );
}
答案 5 :(得分:0)
试试这个..
class CompareByX
{
operator ()(const GameEntity &a, const GameEntity &b) { ... };
};
...
std::sort( this->begin(), this->end(), CompareByX);
简而言之,函子是一个函数对象--STL专门查找一个operator(),它接受我指定的两个参数。如果您是C ++的新手,我建议您查找运算符和仿函数 - 即使在STL之外它们也非常方便。
编辑:杰瑞的答案更好,更全面。