 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Toto Le Ouf Guest
|
Posted: Sat Jun 11, 2005 11:59 am Post subject: vector<>::iterator et NULL |
|
|
Bonjour, j'ai un petit problème :
je déclare des itérateurs ainsi (Student et Semestre sont des classes
définies correctement, normalement...) :
vector<Student>::iterator i ;
list<Semestre>::iterator j ;
je les initialise :
i = NULL;
j = NULL;
et voici le résultat du compilo :
102 D:XXXMini-ProjetZZZtest.cpp no match for 'operator=' in 'i = 0'
Une idée ? Pourquoi cela fonctionne-t-il avec list<> et non avec vector<> ?
Merci.
T.
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Sat Jun 11, 2005 1:50 pm Post subject: Re: vector<>::iterator et NULL |
|
|
Toto Le Ouf wrote:
| Quote: | je déclare des itérateurs ainsi (Student et Semestre sont des classes
définies correctement, normalement...) :
vector<Student>::iterator i ;
list<Semestre>::iterator j ;
je les initialise :
i = NULL;
j = NULL;
|
Dans quel but ? Qu'est-ce que cela devrait donner d'après toi ?
D'habitude, on ne déclare et initialise les itérateurs que lorsqu'on
sait avec quoi :
std::vector<Student>::iterator i = std::find(AllStudents.begin(),
AllStudents.end(),
Student("Toto Le Ouf"));
for(std::list<Semestre>::iterator j = AllSemesters.begin();
j != AllSemesters.end();
++j)
{
// ...
}
| Quote: | et voici le résultat du compilo :
102 D:XXXMini-ProjetZZZtest.cpp no match for 'operator=' in 'i = 0'
Une idée ? Pourquoi cela fonctionne-t-il avec list<> et non avec vector<> ?
|
La Norme ne prévoit pas que l'on puisse affecter 0 à un itérateur -
les itérateurs ne sont pas des pointeurs même s'ils y ressemblent.
Il se peut que cela compile sur certaines implémentations, surtout
avec 'std::vector<toto>::iterator' car parfois celui-ci est simplement
un typedef pour 'toto*' - mais ce n'est pas vrai partout, donc il ne
faut pas compter la dessus.
Autre question: Es-tu sûr que les classes 'Student' et 'Semestre' doivent
avoir une sémantique de valeur, c.a.d. si des étudiants et semestres doivent
être librement copiables ? Cela voudrait dire que tu auras probablement
plusieurs copies (instances) d'un même étudiant dans ton programme, et
une mise à jour des attributs d'une instance (cours auxquels il participe,
notes etc.) ne se répercutera pas sur les autres instances. Cela me semble
bizarre...
Tu veux peut-être plutôt
std::vector<Student*>
ou
std::vector<boost::shared_ptr
à la place de
std::vector<Student>
puis rendre le constructeur de copie et l'affectation 'private' (et sans
implémentation) dans la classe 'Student', de manière à lui donner une
sémantique de référence (c.a.d. pour chaque étudiant, il n'existera qu'une
instance le représentant dans le programme, qui sera manipulée par des
références ou pointeurs) ?
Falk
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Sat Jun 11, 2005 1:56 pm Post subject: Re: vector<>::iterator et NULL |
|
|
Toto Le Ouf wrote:
| Quote: | je déclare des itérateurs ainsi (Student et Semestre sont des classes
définies correctement, normalement...) :
vector<Student>::iterator i ;
list<Semestre>::iterator j ;
je les initialise :
i = NULL;
j = NULL;
|
Dans quel but ? Qu'est-ce que cela devrait donner d'après toi ?
D'habitude, on ne déclare et initialise les itérateurs que lorsqu'on
sait avec quoi :
std::vector<Student>::iterator i = std::find(AllStudents.begin(),
AllStudents.end(),
Student("Toto Le Ouf"));
for(std::list<Semestre>::iterator j = AllSemesters.begin();
j != AllSemesters.end();
++j)
{
// ...
}
| Quote: | et voici le résultat du compilo :
102 D:XXXMini-ProjetZZZtest.cpp no match for 'operator=' in 'i = 0'
Une idée ? Pourquoi cela fonctionne-t-il avec list<> et non avec vector<> ?
|
La Norme ne prévoit pas que l'on puisse affecter 0 à un itérateur -
les itérateurs ne sont pas des pointeurs même s'ils y ressemblent.
Il se peut que cela compile sur certaines implémentations, surtout
avec 'std::vector<toto>::iterator' car parfois celui-ci est simplement
un typedef pour 'toto*' - mais ce n'est pas vrai partout, donc il ne
faut pas compter là-dessus.
Autre question: Es-tu sûr que les classes 'Student' et 'Semestre' doivent
avoir une sémantique de valeur, c.a.d. si des étudiants et semestres doivent
être librement copiables ? Cela voudrait dire que tu auras probablement
plusieurs copies (instances) d'un même étudiant dans ton programme, et
une mise à jour des attributs d'une instance (cours auxquels il participe,
notes etc.) ne se répercutera pas sur les autres instances. Cela me semble
bizarre...
Tu veux peut-être plutôt
std::vector<Student*>
ou
std::vector<boost::shared_ptr
à la place de
std::vector<Student>
puis rendre le constructeur de copie et l'affectation 'private' (et sans
implémentation) dans la classe 'Student', de manière à lui donner une
sémantique de référence (c.a.d. pour chaque étudiant, il n'existera qu'une
instance le représentant dans le programme, qui sera manipulée par des
références ou pointeurs) ?
Falk
|
|
| Back to top |
|
 |
Toto Le Ouf Guest
|
Posted: Sat Jun 11, 2005 4:11 pm Post subject: Re: vector<>::iterator et NULL |
|
|
| Quote: | Dans quel but ? Qu'est-ce que cela devrait donner d'après toi ?
D'habitude, on ne déclare et initialise les itérateurs que lorsqu'on
sait avec quoi :
std::vector<Student>::iterator i = std::find(AllStudents.begin(),
AllStudents.end(),
Student("Toto Le Ouf"));
for(std::list<Semestre>::iterator j = AllSemesters.begin();
j != AllSemesters.end();
++j)
{
// ...
}
La Norme ne prévoit pas que l'on puisse affecter 0 à un itérateur -
les itérateurs ne sont pas des pointeurs même s'ils y ressemblent.
Il se peut que cela compile sur certaines implémentations, surtout
avec 'std::vector<toto>::iterator' car parfois celui-ci est simplement
un typedef pour 'toto*' - mais ce n'est pas vrai partout, donc il ne
faut pas compter là-dessus.
|
En réalité, j'ai un vecteur d'étudiant (vector<Student> _vecteur) et un
itérateur sur celui ci (vector<Student>::iterator i) qui représente
l'étudiant courant
J'ai une fonction qui me permet de supprimer l'étudiant courant du vecteur
(elle utilise _vecteur.erase(i) ) et à chaque fois que j'utilise cette
fonction, je décrémente l'itérateur i. Donc, quand je vais supprimer le
dernier étudiant, i sera décrémenté et ne pointera plus sur rien, d'où une
erreur d'execution quand j'essaierai de supprimer encore un étudiant.
A part, regarder si la taille du vecteur n'est pas de 0, n'y a-t-il pas une
autre solution ?
Merci.
T.
|
|
| Back to top |
|
 |
Richard Delorme Guest
|
Posted: Sat Jun 11, 2005 4:35 pm Post subject: Re: vector<>::iterator et NULL |
|
|
Toto Le Ouf a écrit :
| Quote: | En réalité, j'ai un vecteur d'étudiant (vector<Student> _vecteur) et un
itérateur sur celui ci (vector<Student>::iterator i) qui représente
l'étudiant courant
J'ai une fonction qui me permet de supprimer l'étudiant courant du vecteur
(elle utilise _vecteur.erase(i) ) et à chaque fois que j'utilise cette
fonction, je décrémente l'itérateur i. Donc, quand je vais supprimer le
dernier étudiant, i sera décrémenté et ne pointera plus sur rien, d'où une
erreur d'execution quand j'essaierai de supprimer encore un étudiant.
A part, regarder si la taille du vecteur n'est pas de 0, n'y a-t-il pas une
autre solution ?
|
un reverse_iterator ?
--
Richard
|
|
| Back to top |
|
 |
Arnaud Debaene Guest
|
Posted: Sun Jun 12, 2005 12:07 pm Post subject: Re: vector<>::iterator et NULL |
|
|
Toto Le Ouf wrote:
| Quote: | J'ai une fonction qui me permet de supprimer l'étudiant courant du
vecteur (elle utilise _vecteur.erase(i) ) et à chaque fois que
j'utilise cette fonction, je décrémente l'itérateur i.
C'est là qu'est ton erreur : vector.erase invalide l'itérateur qui lui est |
passé, donc tu ne peux plus rien faire de cet itérateur, même pas
l'incrémenter ou le décrémenter. Par contre, vector.erase renvoie un autre
itérateur sur l'objet suivant dans le vector (ou sur end) : c'st lui que tu
dois utiliser pour poursuivre ton itération sur le vecteur.
Arnaud
|
|
| Back to top |
|
 |
Toto Le Ouf Guest
|
Posted: Sun Jun 12, 2005 12:52 pm Post subject: Re: vector<>::iterator et NULL |
|
|
| Quote: | C'est là qu'est ton erreur : vector.erase invalide l'itérateur qui lui est
passé, donc tu ne peux plus rien faire de cet itérateur, même pas
l'incrémenter ou le décrémenter. Par contre, vector.erase renvoie un autre
itérateur sur l'objet suivant dans le vector (ou sur end) : c'st lui que
tu
dois utiliser pour poursuivre ton itération sur le vecteur.
|
Ok, mais que se passe-t-il quand on supprime le dernier élément du vecteur :
que renvoie la fonction ? un itérateur ? Si oui, sur quoi ?
Merci.
T.
|
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sun Jun 12, 2005 12:56 pm Post subject: Re: vector<>::iterator et NULL |
|
|
On Sun, 12 Jun 2005 14:52:29 +0200, thomas.carpentier :
| Quote: | Ok, mais que se passe-t-il quand on supprime le dernier élément du vecteur :
que renvoie la fonction ? un itérateur ? Si oui, sur quoi ?
|
Arnaud t'a déjà répondu :
| Quote: | Par contre, vector.erase renvoie un autre
itérateur sur l'objet suivant dans le vector (ou sur end)
|
Note que la fonction vector<>::erase() renvoie forcément un iterateur,
puisque c'est son type de retour. Et si le vector<> est vide, le seul
itérateur qui puisse être renvoyé est end().
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|