Déclarant foncteurs pour la comparaison?
J'ai vu d'autres questions de personnes, mais n'en trouva aucun qui s'appliquait à ce que je suis en train de réaliser ici.
Je suis en train de trier des Entités par l'intermédiaire de ma classe EntityManager en utilisant std::sort et un 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 ça pourrait être le problème lors de l'utilisation de la compareByX foncteur ?
Je suis assez novice en C++, de sorte que toute aide est donc la bienvenue.
Avez-vous mélanger
Par ailleurs, ce que vous souhaitez atteindre?
Remarque: la modification de la question comme ça va être difficile pour vous de choisir la "bonne" réponse 🙂
Entity
et GameEntity
classes?Par ailleurs, ce que vous souhaitez atteindre?
Remarque: la modification de la question comme ça va être difficile pour vous de choisir la "bonne" réponse 🙂
OriginalL'auteur Goles | 2009-11-19
Vous devez vous connecter pour publier un commentaire.
Et un troisième arrive... Après avoir édité de te remettre en question, encore un sujet ouvert: votre comparateur prend un
const &
à laGameEntity
classe. Il devrait, afin de travailler avec les valeurs de lavector<GameEntity*>
, prendreconst GameEntity*
arguments à la place.OriginalL'auteur xtofl
Un foncteur est une classe qui définit l'opérateur() pour un objet de cette classe peut être "invoquée" avec la même syntaxe que l'appel d'une fonction:
Si vous voulez que comme un membre de votre classe d'Entité, vous pouvez utiliser une classe imbriquée:
Alors votre tri ressemblerait à quelque chose comme ceci:
Alternativement, si vous avez l'habitude de tri des Entités du X, vous pouvez définir l'opérateur< pour l'Entité:
Dans ce cas, votre utilisation de tri serait un peu plus simple:
De la création de la fonction de comparaison comme un membre normal de la fonction de la classe d'Entité, cependant, va conduire à une sorte d'invocation, c'est assez moche -- c'aurez généralement besoin de quelque chose comme std::mem_fun_ref pour faire le travail, il est suffisamment moche que j'avais généralement à éviter pour de vrai code.
Si vous voulez prendre le "struct foncteur", où voulez-vous place de cette structure ? au sein de l'Entité.h par exemple ? ( juste pour garder les choses en ordre, je veux dire )
pas si -- byX est juste le nom d'un type. byX() crée un objet temporaire de ce type. std::sort sera alors invoquer l'opérateur() sur cet objet.
Gando: où mettre le comparateur dépend de l'utilisation. Si c'est fondamentalement partie de l'Entité, et ne jamais utilisé pour trier les objets de l'Entité, alors je serais probablement l'intégrer au sein de l'Entité à la définition, au sein de l'Entité.h. Dans certains cas, la même comparaison peut être utilisé sur un certain nombre de types différents, auquel cas il assume sa propre identité, plutôt que de faire partie de quelque chose d'autre.
drôle, Joie demandé la même chose lors de la lecture de ma réponse 🙂
OriginalL'auteur Jerry Coffin
Je l'ai fait voir à cette question, récemment, quoique....
La réponse était quelque chose dans le sens de: la fonction de
sort
ne doit pas être un membre de la fonction de quelque chose. Signification: elle doit être une fonction statique, ou une fonction libre. Dans le cas où vous déclarez une fonction statique, vous devez toujours faire précéder parEntity::compareByX
dans le but de les nommer correctement.Si vous définissez l'ordre dans la classe elle-même, vous pouvez, comme aJ déjà dit, l'utilisation d'une fonction d'adaptateur
mem_fun
oumem_fun_ref
pour la verser dans une "libre" foncteur objet.Si vous voulez un
Entity
un objet pour en faire la comparaison, vous devez fournirsort
avec un objet (appelé foncteur ou de comparaison dans ce cas):std::sort( v.begin(), v.end(), EntityComp );
Je suis en train de faire: std::sort(entityList.begin(), entityList.end(), std::mem_fun(&Entité::compareByX()); ,mais j'obtiens l'erreur: no matching function for call to 'Entité::compareByX()' . d'Entité::compareByX, la bonne façon de passer cet argument ?
n'entraînera pas un objet, ni une fonction.
EntityComp()
entraînera une temporaire foncteur objet, passé à lasort
fonction. Vous pouvez ainsi construire leEntityComp
d'avance, commeEntityComp e; sort( .... e );
.En effet:
&Entity::compareByX()
est littéralement: "l'adresse du résultat d'un appel à compareByX... But you can only call
compareByX" sur un puisque c'est une fonction membre. Deux erreurs: vous devez faire la fonctionstatic
, et vous n'avez pas besoin de l'appeler, mais donnersort
d'adresse, commesort( .... , &Entity::compareByX );
. Si vous êtes à la prise de la fonctionstatic
, il n'est pas nécessaire de créer une classe pour elle - il suffit de faire une fonction libre.par "libres", tu veux dire utiliser quelque chose comme ceci ? : struct compareByX{ bool operator()(const GameEntity &a, const GameEntity &b) { return (un.x < b.x); } }
OriginalL'auteur xtofl
Je crois
compareByX
devrait être unstatic
membre ou d'un lac un coup d'oeil iciOriginalL'auteur Elalfer
À la lumière de ce que vous essayez d'atteindre", je peux faire une autre proposition... Vous voulez être en mesure de préciser si la comparaison de vos objets par leur
GameEntity::x
membre, ou par leurGameEntity::y
membre.Le plus simple serait d', comme vous l'avez fait, spécifiez un foncteur pour chaque membre:
Le "flexible" encore plus difficile serait de créer un modèle foncteur:
OriginalL'auteur xtofl
essayer..
En un mot, un foncteur est une fonction de l'objet de la STL s'intéresse spécifiquement pour un opérateur () qui prend deux paramètres que j'ai spécifié. Si vous êtes novice en C++, je vous suggère de regarder les opérateurs et les foncteurs - ils sont assez pratique, même en dehors de la STL.
Edit: Jerry de réponse est meilleur et plus complet.
OriginalL'auteur Fox