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

question sur list::iterator

6 réponses
Avatar
Aurélien Barbier-Accary
Bonjour,

J'ai des polygones convexes définis par des listes et je cherche une
intersection. Pour ça j'effectue le code suivant :

list<MPoint3D>::iterator ipv1;
list<MPoint3D>::reverse_iterator ipv2;
bool inter_polygons_exists = false;
MPoint3D inter_polygons;
for(ipv1=++poly1->begin(); (!inter_polygons_exists) && (ipv1!=poly1->end()); ipv1++)
for(ipv2=++poly2->rbegin(); (!inter_polygons_exists) &&
(ipv2!=poly2->rend()); ipv2++)
inter_polygons = intersectCoplanarSegments(*(--ipv1),*(++ipv1),
*(--ipv2),*(++ipv2), inter_polygons);

Est-on vraiment obligé de passer par l'écriture (moche) *(--ipv1) puis *(++ipv1)
pour désigner les 2 sommets d'un segment ? Y'a-t-il une raison pour laquelle il
n'existe pas d'opérateur + pour les Bidirectionnal iterators ?

Merci pour vos lumières.

--
Aurélien Barbier-Accary

6 réponses

Avatar
Aurélien Barbier-Accary
Il faut bien sûr lire :

[...]
inter_polygons_exists = intersectCoplanarSegments [...]
[...]


mais ça n'a rien à voir avec le "problème"...

Avatar
Falk Tannhäuser
Aurélien Barbier-Accary wrote:
inter_polygons_exists = intersectCoplanarSegments(*(--ipv1), *(++ ipv1),
*(--ipv2), *(++ip v2),
inter_polygons);

Est-on vraiment obligé de passer par l'écriture (moche) *(--ipv1) p uis
*(++ipv1) pour désigner les 2 sommets d'un segment ? Y'a-t-il une rai son
pour laquelle il n'existe pas d'opérateur + pour les Bidirectionnal
iterators ?


C'est non seulement moche et illisible mais ça donne surtout un
comportement indéfini - il n'y a pas de "points de séquence"
entre les évaluations des arguments lors de l'appel d'une fonction,
donc on ne sait pas dans quel ordre les ++ et -- sont appliqués.

Une solution possible :

template<typename Iter> inline Iter predecessor(Iter it)
{
return --it;
}

... intersectCoplanarSegments(*predecessor(ipv1), *ipv1,
*predecessor(ipv2), *ipv2,
inter_polygons);


Falk

Avatar
Jean-Marc Bourguet
Aurélien Barbier-Accary writes:

Est-on vraiment obligé de passer par l'écriture (moche) *(--ipv1) puis
*(++ipv1) pour désigner les 2 sommets d'un segment ?


Voir std::advance

Y'a-t-il une raison pour laquelle il n'existe pas d'opérateur + pour
les Bidirectionnal iterators ?


Parce que la complexite ne serait pas en temps constant.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Aurélien Barbier-Accary
template<typename Iter> inline Iter predecessor(Iter it)
{
return --it;
}

... intersectCoplanarSegments(*predecessor(ipv1), *ipv1,
*predecessor(ipv2), *ipv2,
inter_polygons);


Falk


Merci.
Je trouve étrange qu'une telle fonction n'existe pas de base dans la STL !?!!

--
Aurélien Barbier-Accary

Avatar
Aurélien Barbier-Accary
Aurélien Barbier-Accary writes:

Est-on vraiment obligé de passer par l'écriture (moche) *(--ipv1) puis
*(++ipv1) pour désigner les 2 sommets d'un segment ?


Voir std::advance


le problème c'est que advance comme operator++ modifient l'itérateur alors que
moi je voudrais obtenir son précédent sans modifier ipv1.
La solution proposée par Falk Tannhäuser fait ce que je souhaite mais je
n'arrive pas à être convaincu qu'il n'y a pas un tel mécanisme interne à la STL...

Y'a-t-il une raison pour laquelle il n'existe pas d'opérateur + pour
les Bidirectionnal iterators ?


Parce que la complexite ne serait pas en temps constant.



ce qui n'est pas bien grave, il suffit de le savoir. De toute façon advance ou n
appels à ++ sont également effectués en O(n).

En tout cas merci de ta réponse, je ne connaissais pas advance.

--
Aurélien Barbier-Accary


Avatar
Pierre Barbier de Reuille
Bonjour,

J'ai des polygones convexes définis par des listes et je cherche une
intersection. Pour ça j'effectue le code suivant :

list<MPoint3D>::iterator ipv1;
list<MPoint3D>::reverse_iterator ipv2;
bool inter_polygons_exists = false;
MPoint3D inter_polygons;
for(ipv1=++poly1->begin(); (!inter_polygons_exists) &&
(ipv1!=poly1->end()); ipv1++)
for(ipv2=++poly2->rbegin(); (!inter_polygons_exists) &&
(ipv2!=poly2->rend()); ipv2++)
inter_polygons = intersectCoplanarSegments(*(--ipv1),*(++ipv1),
*(--ipv2),*(++ipv2), inter_polygons);

Est-on vraiment obligé de passer par l'écriture (moche) *(--ipv1) puis
*(++ipv1) pour désigner les 2 sommets d'un segment ? Y'a-t-il une raison
pour laquelle il n'existe pas d'opérateur + pour les Bidirectionnal
iterators ?

Merci pour vos lumières.



Et pourquoi pas tout simplement :


list<MPoint3D>::iterator ipv11, ipv12 = poly1->begin();
list<MPoint3D>::reverse_iterator ipv21, ipv22 = poly2->rbegin();
MPoint3D inter_polygons;
bool inter_polygons_exists = false;
for( ipv11 = ipv12++ ; (!inter_polygons_exists) &&
(ipv12!=poly1->end()); ipv11++, ipv12++)
{
for(ipv21 = ipv22++; (!inter_polygons_exists) &&
(ipv22!=poly2->rend()); ipv21++, ipv22++)
{
inter_polygons_exists = intersectCoplanarSegments(*ipv11,*pv12,
*ipv21,*ipv22, inter_polygons);
}
}

Ce qui évite tous les problèmes d'ordre d'évaluation et fait ce que tu
veux ...

Pierre