Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[GCC] std::set::iterator

6 réponses
Avatar
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>

6 réponses

Avatar
Jean-Sebastien Mouret
Franck Branjonneau writes:

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

Avatar
Franck Branjonneau
Jean-Sebastien Mouret écrivait:

Franck Branjonneau writes:


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


Avatar
Franck Branjonneau
Jean-Sebastien Mouret écrivait:

Franck Branjonneau writes:

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


Avatar
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, 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

Avatar
Franck Branjonneau
Anthony Fleury écrivait:

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


Avatar
Anthony Fleury
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