2 votes

Quel type de retour dois-je utiliser pour une affectation de pointeur ?

J'ai une structure comme celle-ci :

struct group
{
    int index; 
    string name; 
    group* child;

};

Et j'ai mis en place un vecteur pour stocker quelques structs de groupe.

J'essaie maintenant d'avoir une fonction pour récupérer un membre du groupe à partir de ce vecteur par index, quelque chose comme ceci :

148    newGroup.child = getGroupByIndex(world, i);

Et la définition de la fonction est :

group& getGroupByIndex(vector<group>* world, int i)
{
    for(vector<group>::iterator it = world->begin();
        it < world->end(); ++it)
    {
        if(it->index == i) return *it;
    }
267     return 0;
}

Malheureusement, il ne compile même pas.

Et le message d'erreur est :

tree.cpp: In function ‘int main()’: 
tree.cpp:148: error: cannot convert ‘group’ to ‘group*’ in assignment 
tree.cpp: In function ‘group& getGroupByIndex(std::vector<group, std::allocator<group> >*, int)’: 
tree.cpp:267: error: invalid initialization of non-const reference of type ‘group&’ from a temporary of type ‘int’

Mes deux problèmes,

  1. comment corriger l'erreur de compilation ? quel type de retour dois-je utiliser ?

  2. Si je veux renvoyer un pointeur nul à la ligne 267, que dois-je utiliser ? J'ai essayé (void *)0 et 0, mais aucun des deux ne fonctionne.

0voto

M M. Points 29201

Je pense que ça devrait être comme ça :

group* getGroupByIndex(vector<group*> world, int i) // See position of two *
{
    for(vector<group*>::iterator it = world.begin();
        it < world.end(); ++it)
    {
        if(it->index == i)
          return *it;
    }
    return 0;
}

ou

group* getGroupByIndex(vector<group> *world, int i) // See position of two *
{
    for(vector<group>::iterator it = world->begin();
        it < world->end(); ++it)
    {
        if(it->index == i)
          return &(*it);
    }
    return 0;
}

0voto

Laurent Points 442

Si vous voulez préférer les références aux pointeurs, vous pouvez également définir un objet de groupe "non trouvé" qui sera renvoyé par votre fonction.

Je ferais ça comme ça :

struct group
{
    int index; 
    string name; 
    group* child;
    group(int i):index(i),child(null){}
    group(int i, const string& n, group& c):index(i), name(n), child(&c){}

    // assuming index defines the uniqueness of your object class
    bool operator == (const struct group& g)const {return (index == g.index);}

    // an unique special instance of group struct
    static struct group not_found;
};
group group::not_found(-1);

Vous pouvez donc définir votre fonction comme vous le souhaitez :

group& getGroupByIndex(vector<group>* world, int i)
{
    for(vector<group>::iterator it = world->begin();
        it < world->end(); ++it)
    {
        if(it->index == i) return *it;
    }
    return group::not_found; // a reference to a special singleton instance of struct group
}

et vous serez en mesure de faire des appels comme ceci :

...
group& g = getGroupByIndex(world, index);
if(g == group::not_found)
{
   // handle the not found case here
   ...

0voto

Bartek Banachewicz Points 13173

Utilisez

boost::optional

Première règle du C++ moderne : ne pas utiliser de pointeurs ****.

boost::optional<group&> get(vector<group>& world, int i)
{
    for(auto & grp : world)
    {
        if(grp.index == i)
           return boost::optional<group&>(grp);
    }
    return boost::none;
}

Veuillez noter que cette solution a O(n) complexité. Si vous souhaitez effectuer une recherche sur la base de index je recommande d'utiliser une structure qui a des références à group objets triés par index ce qui vous donnerait O(log n) temps de recherche.

Dans ce cas, je tiendrais probablement un vecteur de shared_ptr et un map<int, weak_ptr> . Vous pouvez également consulter boost::multi_index

Ah, et juste une note en marge de votre 2) point que je viens de remarquer : nullptr .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X