4

我见过其他人的问题,但没有发现适用于我在这里想要实现的目标。

我正在尝试使用 std::sort 和 a 通过我的 EntityManager 类对实体进行排序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++ 很陌生,所以欢迎任何形式的帮助。

4

6 回答 6

5

第三个进来了......在你编辑了你的问题之后,还有一个开放的话题:你的比较器需要一个const &班级GameEntity。为了使用 的值,它应该vector<GameEntity*>取而代之 const GameEntity*的是参数。

于 2009-11-19T19:44:43.267 回答
4

仿函数是定义 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 对实体进行排序,您可以为实体定义 operator<:

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 之类的东西来完成这项工作;它非常丑陋,以至于我通常会在实际代码中避免使用它。

于 2009-11-19T19:06:36.010 回答
2

不过最近我确实看到了这个问题......

答案是这样的:提供给的函数sort不应该是某物的成员函数。含义:它应该是一个静态函数,或者一个自由函数。如果您将其声明为静态函数,您仍应在其前面Entity::compareByX添加以正确命名它。

如果您在类本身中定义顺序,则可以如 aJ 所述,使用函数适配器mem_funmem_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() );
于 2009-11-19T18:39:24.490 回答
1

我相信compareByX应该是static会员或湖看看这里

于 2009-11-19T18:45:06.833 回答
1

鉴于“您要达到的目标”,我可能会再做一次猜测……您希望能够指定是按其GameEntity::x成员还是按其GameEntity::y成员来比较您的对象。

最简单的方法是像您一样为每个成员指定一个仿函数:

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" ) );
}
于 2009-11-19T19:21:38.087 回答
0

尝试这个..

 class CompareByX
 {
   operator ()(const GameEntity &a, const GameEntity &b) { ... };
 };

 ...
 std::sort( this->begin(), this->end(), CompareByX);

简而言之,仿函数是一个函数对象——STL 专门寻找一个接受我指定的两个参数的运算符 ()。如果您是 C++ 新手,我建议您查找运算符和函子 - 即使在 STL 之外,它们也非常方便。

编辑:杰里的答案更好,更全面。

于 2009-11-19T19:09:56.143 回答