[GCC] std::set::iterator

Le
Franck Branjonneau
J'ai mis à jour (GCC-3.3) mon compilateur et le code suivant ne
compile plus.

std::set< int > s;
int * i(&*s.insert(5).first);

J'ai une : invalid conversion from `const int*' to `int*'.

En allant voir où je ne devrais pas ;-) <bits/stl_set.h> je trouve :

typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_reverse_iterator reverse_iterator;

[]

/**
* Returns a read/write iterator that points to the first element in
* the %set. Iteration is done in ascending order according to the keys.
*/
iterator
begin() const

[ Pas de version non const, de même pour end(), rbegin() et rend() ]

[ insert, find, upper(resp. lower)_bound ont des signatures
cohérentes. ]


J'ai vérifié sur mainline d'hier, j'ai la même chose.


C'est tellement gros que je doute Suis-je complètement à côté de la
plaque ?
--
Franck Branjonneau <fasbjx@free.fr>
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Sebastien Mouret
Le #168759
Franck Branjonneau
J'ai mis à jour (GCC-3.3) mon compilateur et le code suivant ne
compile plus.

std::set< int > s;
int * i(&*s.insert(5).first);

J'ai une : invalid conversion from `const int*' to `int*'.



Ca me parait etre un comportement cohérent. Avoir un pointeur
non-const sur l'int stocké dans le set permettrait de modifier la
valeur de l'int sans que le set ne s'en apercoive. Il peut donc plus
assurer que les éléments sont ordonnés correctement, et perd son
intégrité.

--

"creating the future" (c) framfab

Franck Branjonneau
Le #168687
Jean-Sebastien Mouret
Franck Branjonneau

std::set< int > s;
int * i(&*s.insert(5).first);

J'ai une : invalid conversion from `const int*' to `int*'.



Ca me parait etre un comportement cohérent. Avoir un pointeur
non-const sur l'int stocké dans le set permettrait de modifier la
valeur de l'int sans que le set ne s'en apercoive. Il peut donc plus
assurer que les éléments sont ordonnés correctement, et perd son
intégrité.


Oui, j'aurais du réfléchir un peu plus. Merci.
--
Franck Branjonneau

Franck Branjonneau
Le #168686
Jean-Sebastien Mouret
Franck Branjonneau
J'ai mis à jour (GCC-3.3) mon compilateur et le code suivant ne
compile plus.

std::set< int > s;
int * i(&*s.insert(5).first);

J'ai une : invalid conversion from `const int*' to `int*'.



Ca me parait etre un comportement cohérent. Avoir un pointeur
non-const sur l'int stocké dans le set permettrait de modifier la
valeur de l'int sans que le set ne s'en apercoive. Il peut donc plus
assurer que les éléments sont ordonnés correctement, et perd son
intégrité.


Oui, j'aurais du réfléchir un peu plus. Merci
--
Franck Branjonneau

Anthony Fleury
Le #168683
Franck Branjonneau wrote:

Bonjour, petit complément :

[...]

/**
* Returns a read/write iterator that points to the first element in
* the %set. Iteration is done in ascending order according to the keys.
*/
iterator
begin() const

[ Pas de version non const, de même pour end(), rbegin() et rend() ]


Je ne sais pas si je comprends mal ou pas ta remarque, mais il n'y a en
aucun cas à avoir de version non const de ces fonctions. Que ce soit pour
un conteneur qui retourne un iterateur qui te permet une modification de
l'objet référencé, ou un qui ne te le permet pas, dans tous les cas les
fonctions begin() end() et leurs versions reverse ne modifient en rien
l'état de ta classe. Elles ont donc bien à être mises constantes pour
pouvoir être appelées sur des objets constants.

Anthony
--
"I should have seen it would be this way
I should have known from the start what she's up to
When you have loved and you've lost someone
You know what it feels like to lose" -- The Rasmus

Franck Branjonneau
Le #168680
Anthony Fleury
Franck Branjonneau wrote:

Bonjour, petit complément :

[...]

/**
* Returns a read/write iterator that points to the first element in
* the %set. Iteration is done in ascending order according to the keys.
*/
iterator
begin() const

[ Pas de version non const, de même pour end(), rbegin() et rend() ]


Je ne sais pas si je comprends mal ou pas ta remarque,


Ma remarque est cohérente avec le reste de mon message, mais erronée.

mais il n'y a en aucun cas à avoir de version non const de ces
fonctions.


Cette fois c'est toi qui est dans l'erreur.

Que ce soit pour un conteneur qui retourne un iterateur
qui te permet une modification de l'objet référencé, ou un qui ne te
le permet pas, dans tous les cas les fonctions begin() end() et
leurs versions reverse ne modifient en rien l'état de ta
classe. Elles ont donc bien à être mises constantes pour pouvoir
être appelées sur des objets constants.


Non. La version const te renvoie un const_iterator : tu es assuré que
tu ne modifieras pas ton container, déclaré const, au travers de
itérateur retourné ; la version non const te renvoie un iterator : tu
est libre de modifier un container, non déclaré const, au travers de
cet itérateur.

Cf. std::vector, par exemple.
--
Franck Branjonneau

Anthony Fleury
Le #168600
Franck Branjonneau wrote:

[...]
Discussion sur begin(), end() et autres...

Non. La version const te renvoie un const_iterator : tu es assuré que
tu ne modifieras pas ton container, déclaré const, au travers de
itérateur retourné ; la version non const te renvoie un iterator : tu
est libre de modifier un container, non déclaré const, au travers de
cet itérateur.

Cf. std::vector, par exemple.


Oups oui pardon, je ne suis pas réveillé du tout !! [8h de cours c'est une
excuse?]
Pouvoir modifier un itérateur constant avec begin() qui est censé nous
permettre de modifier un container est assez idiot... Désolé de cette
erreur _énorme_.

Anthony
--
"I should have seen it would be this way
I should have known from the start what she's up to
When you have loved and you've lost someone
You know what it feels like to lose" -- The Rasmus

Publicité
Poster une réponse
Anonyme