web-dev-qa-db-fra.com

Puis-je vérifier un itérateur C ++ contre null?

J'ai des problèmes avec les itérateurs vectoriels. J'ai lu à quelques endroits que la recherche d'itérateurs nuls n'est pas possible, et que la manière habituelle de vérifier les itérateurs est de la comparer à vector.end () après une recherche. Ainsi, par exemple:

vector< Animal* > animalList;

vector<Animal*>::iterator findInList(const type_info& type)
{
    // Loop through list of Animals, if Dog found, return iterator to it
}

auto it = findInList(typeid(Dog));
// With a pointer I can check if it's null, but with an iterator I have to check against animalList.end();

Le problème est que le conteneur peut être vide. Avec un itérateur, je ne peux pas retourner null pour indiquer que le conteneur est vide ou que la recherche a échoué. Je peux retourner vector :: end (), mais cplusplus.com dit:

If the container is empty, vector::end() function returns the same as vector::begin()

puis pour vector :: begin () il dit:

If the container is empty, the returned iterator value shall not be dereferenced.

Donc, si j'ai un conteneur vide, vector :: end () et vector :: begin () pointent au même endroit, je ne pense pas pouvoir le déréférencer, et je ne suis même pas sûr qu'il pointe vers la mémoire allouée.

Edit: Merci à tous. Comme vous l'avez répété, vector :: end () ou vector :: begin () ne déréférencent pas l'itérateur, je peux vérifier en toute sécurité contre vector :: end ().

12
Zebrafish

Vous n'avez pas besoin de vérifier si l'itérateur est nul, car il ne le sera jamais. Vous devez vérifier si l'itérateur retourné est différent de la position des conteneurs end(). Si c'est le cas, vous pouvez déréférencer l'itérateur en toute sécurité par *it.

Si le conteneur est vide, la valeur de l'itérateur retourné ne doit pas être déréférencée. Donc, si j'ai un conteneur vide, vector :: end () et vector :: begin () pointent au même endroit, je ne pense pas pouvoir le déréférencer, et je ne suis même pas sûr qu'il pointe vers la mémoire allouée.

Non, en vérifiant if(myIt != container.end()) cela ne fait pas de déréférencement de l'itérateur. La déréférence de l'itérateur est *myIt, Ce qui signifie obtenir la valeur de l'objet vers lequel l'itérateur pointe. Il est toujours sûr de vérifier les itérateurs vers d'autres itérateurs du même conteneur, il est dangereux de déréférencer l'itérateur qui ne pointe pas vers les éléments de conteneurs.

17
paweldac

Non, vous ne pouvez pas vérifier la valeur NULL car ce n'est pas un pointeur. Retournez et vérifiez également contre animalList.end(). Ce n'est que lorsque l'itérateur n'est pas égal à end() que vous devez le déréférencer.

3
Mikel F

Vérifiez comme ça

auto it = findInList( someInfo );

if ( it == animalList.end() ) std::cout << "not found";
2
Vlad from Moscow