OVH Cloud OVH Cloud

Contrainte sur les itérateurs.

15 réponses
Avatar
Mickaël Wolff
Bonjour,

Est-ce une erreur que de croire que la différence entre deux
itérateurs, avec l'opérateur -, fait sens ?

Je pose la question parce que je suis tombé sur un itérateur,
Gtk::TextBuffer::iterator, qui ne fournissait pas cet opérateur, ce qui
fait que l'itérateur se castait en bool (ce qui est ballot).

Finalement j'utilises std::difference. Mais c'est surprenant quand on
a l'habitude d'utiliser l'arithmétique des pointeurs, et que les
itérateurs (qui peuvent être confondus avec des pointeurs) ne le
supporte pas totalement.

Merci pour vos avis !
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

5 réponses

1 2
Avatar
Fabien LE LEZ
On Wed, 06 Aug 2008 10:35:21 +0200, Michael DOUBEZ
:

Je suis d'accord mais le cout peut être amorti, par exemple en
maintenant une taille de liste et en l'invalidant en cas de splice;



Oui. Tu peux même encapsuler ça dans une classe à toi. Cf aussi
http://objectmix.com/c/243079-solution-fast-std-list-size-fast-std-list-splice.html

Mais le gars qui a besoin de contraintes fortes sur certaines parties
du code, ne peut pas plus appeler list<>::size(), parce qu'il ne saura
pas si la taille a déjà été calculée ou pas.

en o(n)



Attention aux notations !
Une fonction f est dite en o(n) si f(n)/n tend vers 0 quand n tend
vers l'infini. C'est différent de O(n).
Avatar
Michael DOUBEZ
Fabien LE LEZ a écrit :
On Wed, 06 Aug 2008 10:35:21 +0200, Michael DOUBEZ
:

Je suis d'accord mais le cout peut être amorti, par exemple en
maintenant une taille de liste et en l'invalidant en cas de splice;



Oui. Tu peux même encapsuler ça dans une classe à toi. Cf aussi
http://objectmix.com/c/243079-solution-fast-std-list-size-fast-std-list-splice.html



OK. D'où ma question d'origine sur C++0X.

Vu les réponses, je suppose que ce sera comme avant ou alors que je vais
devoir aller chercher confirmation dans le brouillon (toujours N2691?).

Mais le gars qui a besoin de contraintes fortes sur certaines parties
du code, ne peut pas plus appeler list<>::size(), parce qu'il ne saura
pas si la taille a déjà été calculée ou pas.



A l'heure actuelle, il ne peut déjà pas l'appeler (de façon portable)
puisque list::size() peut déjà être O(n).

Comme je l'ai écrit ce serait bizarre d'avoir à la fois des splices et
une contrainte de calcul de calcul de longueur en O(1):
* soit list est considéré comme un conteneur au même titre que vector
ou deque mais il est sorti gagnant pour la cas considéré, auquel cas
size() en O(1) se justifie
* soit c'est la capacité de décomposition rapide préservant les
itérateurs qui est demandée et donc splice est utilisé activement mais
dans ce cas la taille est rarement un élément déterminant (et AMA ça ne
gène pas si elle est en O(n)).

Le seul point négatif est le cout de maintenir une taille de liste alors
qu'il est peut probable que la taille soit demandée.

Enfin, ce que je trouve aussi intéressant est l'argument de ne pas
fournir de méthode size() si celui ci n'est pas en O(1). De façon
générale, je préfère cette méthode à avoir à lire la doc; et ça
simplifie les concepts: requires has_method_size<T> plutôt que de
spécialiser sur list.

--
Michael
Avatar
Michael DOUBEZ
Michael DOUBEZ a écrit :
je vais devoir aller chercher confirmation dans le brouillon (toujours N2691?).



Il y a bien toujours l'infamant:
Those entries marked “(Note A)” should have constant complexity.

AMHA une note sur list en particulier aurait été la bienvenue.

--
Michael
Avatar
Fabien LE LEZ
On Wed, 06 Aug 2008 11:35:40 +0200, Michael DOUBEZ
:

* soit list est considéré comme un conteneur au même titre que vector
[...] auquel cas
size() en O(1) se justifie
* soit c'est la capacité de décomposition rapide préservant les
itérateurs qui est demandée et donc splice est utilisé activement



Je crois que tu as mis le doigt sur un problème intéressant : ne
faudrait-il pas avoir deux list<> différents ?

Manifestement, la rapidité de splice() est considéré comme le plus
important dans std::list<> ; or j'utilise principalement ce conteneur
comme un vector<> qui n'invalide pas ses itérateurs à tout bout de
champ. Pour bien faire, il me faudrait donc un conteneur hybride. Que
j'ai déjà, d'ailleurs, en utilisant list<> dans VC++.
Avatar
James Kanze
On Aug 6, 9:58 am, Mickaël Wolff wrote:
James Kanze a écrit :



> Oui. Un itérateur itère.



C'est pourtant évident. Mais à force d'utiliser les outils
pour autre chose que ce qu'ils sont, on oublie leur utilité
première.



Surtout quand leur « conception » prévoit tous les abus
explicitement.

> Un itérateur qui se convertit implicitement en bool me semble
> assez louche aussi.



Enjoy ;)



<http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/classGtk_1_1T... >



Aujourd'hui, si on fait du C++, on se trouve devant un dilèmme.
Si on fait proprement, et implémente un itérateur qui ne
supporte que les trois fonctions de base, on ne peut pas s'en
servir avec la STL. Du coup, on est amené à l'étendre. (Dans mon
cas, ça veut dire fournir une fonction isEqual aussi, et dériver
de STLIterator< MyIterator >, qui a tout ce qu'il faut pour
mapper l'interface propre en interface STL.)

> Oui. C'est le genre de problème qui arrive quand on
> surcharge abusivement.



Ça m'apprendra.



Ce n'est pas toi qui a commencé:-).

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
1 2