Question

J'ai vu d'autres personnes, mais des questions ont trouvé aucun qui applique à ce que je suis en train de réaliser ici.

Je suis en train de trier les entités via ma classe EntityManager en utilisant std :: sort et 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);
}

Je reçois une douzaine d'erreurs comme

: error: no match for call to '(compareByX) (GameEntity* const&, GameEntity* const&)'
: note: candidates are: bool compareByX::operator()(const GameEntity&, const GameEntity&)

Je ne suis pas sûr mais ENTITY_VECTOR est std::vector<Entity *>, et je ne sais pas si cela pourrait être le problème lors de l'utilisation du foncteur compareByX?

Je suis assez nouveau pour C ++, de sorte que toute sorte d'aide est la bienvenue.

Était-ce utile?

La solution

Et un troisième arrive ... Après avoir modifié vous question, encore un sujet ouvert: votre comparateur prend un const & à la classe GameEntity. Il devrait, afin de travailler avec les valeurs de la vector<GameEntity*>, prendre des arguments de const GameEntity* à la place.

Autres conseils

A foncteur est une classe qui définit l'opérateur () pour un objet de cette classe peut être « Appelé » avec la même syntaxe que l'appel d'une fonction:

struct functor { 
   bool operator()(Entity const &a, Entity const &b) {
       return a.x < b.x;
   }
};

Si vous voulez qu'en tant que membre de votre classe d'entité, vous utiliseriez une classe imbriquée:

class Entity { 
    float x;
public:
    friend class byX;
    class byX {
        bool operator()(Entity const &a, Entity const &b) { 
            return a.x < b.x;
        }
    };
};

Alors, votre genre ressemblerait à quelque chose comme ceci:

std::sort(ManagedEndities.begin(), ManagedEntities.end(), Entity::byX());

Par ailleurs, si vous triez habituellement par les entités X, vous pouvez définir l'opérateur

class Entity { 
     float x;
public:
     bool operator<(Entity const &other) { 
         return x < other.x;
     }
};

Dans ce cas, votre utilisation de tri serait un peu plus simple:

std::sort(ManagedEntities.begin(), ManagedEntities.end());

Création de la fonction de comparaison en fonction de membre normal de la classe entité, cependant, conduira à une invocation de tri qui est assez laid - ça va généralement besoin de quelque chose comme std :: mem_fun_ref pour faire le travail; il est assez laid que j'évite généralement pour le code réel.

Je l'ai vu cette question, récemment, bien ....

La réponse était quelque chose de la manière de: la fonction fournie à sort ne doit pas être membre fonction de quelque chose. Signification: il doit être une fonction statique, ou une fonction libre. Si vous déclarez une fonction statique, vous devriez toujours précéder par Entity::compareByX afin de le nommer correctement.

Si vous définissez l'ordre dans la classe elle-même, vous pouvez, comme aJ déjà dit, utilisez un adaptateur de fonction mem_fun ou mem_fun_ref de le verser dans un objet foncteur « libre ».

Si vous voulez un objet Entity faire la comparaison, vous devez fournir sort avec un objet (appelé foncteur ou comparateur dans ce cas):

struct EntityComp {
  bool operator()( const GameEntity& a, const GameEntity& b ) const { 
    return a.x < b.x;
  }
}


...
std::sort( v.begin(), v.end(), EntityComp() );

Je crois compareByX devrait être membre de static ou d'un lac un regard

A la lumière de « ce que vous essayez d'atteindre », je faire une autre supposition ... Vous voulez être en mesure de préciser si vous souhaitez comparer vos objets par leur membre de GameEntity::x, ou par un membre de leur GameEntity::y.

La façon la plus simple serait, comme vous l'avez fait, spécifiez un foncteur pour chaque membre:

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 );

Le « flexible » façon encore plus lourde serait de créer un foncteur modèle:

#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" ) );
}

essayer ..

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

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

En un mot, un foncteur est un objet de fonction - la STL recherche spécifiquement un opérateur () qui prend les deux paramètres que je l'ai spécifié. Si vous êtes nouveau C ++, je vous suggère de consulter les opérateurs et foncteurs - ils sont très pratique, même en dehors STL

.

Edit: la réponse de Jerry est meilleure et plus complète

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top