Problem mit find_if in std:: list
-
hmm. achso.. das ist blöd;) muss ich das wohl doch selber machen;)
ich will halt ne funktion mit der ich von einem bst. iterator aus nach recht oder links iterieren kann, bis ein best. iterator CTimeEvent::User(..)== TRUE ist!
musst ich wohl zwei funktionen schreiben
Das Problem ist, das begin () auf das erste existierende element der liste zeigt, und end() auf den iterator nach dem letzen element! so hab ich in beide richtungen untschiedliches verhalten!
-
Ja, du kannst rückwärts suchen - indem du reverse_iteratoren verwendest:
res = std::find(reverse_iterator(iStart),m_lTimeEvents.rend(),...);(rend() ist das Ende der invertierten Daten, zeigt also auf (genauer: vor) den Listen-Anfang)
BorisDieKlinge schrieb:
ja ich prüfe davor ab ob itStart != begin() ist!
Dann wirst du in den meisten Fällen von deiner Startposition aus in Richtung Listenende suchen - und darüber hinaus ins Daten-Nirvana.
-
ahhhh.. genau.. das meinte ich... dann zeigt rend() auf das imaginäre element vor dem ersten, umgekerht aquvivalent wie end() am ende der liste;)
-
PRoblem:
std::list<CTimeEvent>::iterator Prev_WorkEvent(std::list<CTimeEvent>::iterator itStart,UINT iType){ for(std::list<CTimeEvent>::reverse_iterator itStart(++itStart); itStart != m_lTimeEvents.rend(); ++itStart) if(itStart->Used(iType)) return std::list<CTimeEvent>::iterator(itStart); return NULL; }beim return value "Can not konvert reverse_iterator to iterator? wieso nich anderesherum gehts doch auc
-
Es gibt keine implizite Umwandlung von reverse_iteratoren zu "normalen" Iteratoren - wenn du zurückgehen willst, kannst du die Methode base() verwenden.
(wobei - bei deiner handgeschriebenen for-Schleife kannst du auch normale Iteratoren nehmen und dekrementieren ;))
PS: Die Umwandlung von NULL in einen list-Iterator ist auch fragwürdig.
-
oh man so ne scheisse... ich hasse es wenn man was programmiert und es gefällt einen nich:)
P.S:.: rend() == begin()-> also zeigt nicht auf das element davor..
P.P.S: ich muss das mit NULL machen, weil es ja anscheiden kein iteartor vor dem ersten element gibt nur einen nach dem letzten.
-
BorisDieKlinge schrieb:
P.S:.: rend() == begin()-> also zeigt nicht auf das element davor..
Bei reverse-Iteratoren mußt du unterscheiden zwischen physikalischer Position und logischer Position (auf letztere greifst du zu, wenn du den RI dereferenzierst).
Zur Erklärung: Laut Standard gibt es zwar einen Iterator hinter das letzte Container-Element (end() - ist gültig, aber nicht dereferenzierbar), aber keinen Iterator vor das erste Element, deshalb verweisen reverse-Iteratoren physisch auf die Position hinter ihrer logischen Position (rbegin() zeigt physisch auf end() und logisch auf das letzte Element, rend() physisch auf begin() und logisch vor den Datenanfang).
-
ich will einfach nur von ein best. Postion aus (iterator) einfach nach links bzw. nach recht nach dem ersten vorkommenden element mit Used==true iterieren können... aber das ganze scheint nich so einfach zu sein. um eine elegante lösung zu finden!
-
std::list<CTimeEvent>::iterator Prev_WorkEvent(std::list<CTimeEvent>::iterator itStart, UINT iType) { std::list<CTimeEvent>::reverse_iterator start( itStart ); std::list<CTimeEvent>::reverse_iterator end( m_lTimeEvents.rend() ); for ( ; start != end; ++start ) { if ( start->Used( iType ) ) return start.base(); } return m_lTimeEvents.end(); }So?
-
BorisDieKlinge schrieb:
ich will einfach nur von ein best. Postion aus (iterator) einfach nach links bzw. nach recht nach dem ersten vorkommenden element mit Used==true iterieren können... aber das ganze scheint nich so einfach zu sein. um eine elegante lösung zu finden!
Und wovon hängt es ab, ob du nach links oder rechts gehen willst? Im Zweifelsfall gehst du sowohl nach vorn als auch nach hinten und entscheidest dich dann, welchen der (maximal 2) gefundenen Werte du zurückgeben willst.
-
ja so ungefähr.. das problem ist hierbei, wenn itStart( Startposition) den Used==true ist, wird diese zurückgegebe!
@CStoll: ich will einmal das erste vorkommen (itertor) mit dem gleichen typ (used==true) finden in beide richtungen! diese iterator speicher ich dann im element von der startpositon aus, und kann dann direkt zum nächsteh elemt springen..
-
Die Funktion dort (unten) *edit* oben soll aber nur nach vorne suchen, oder wie? Da hast du doch mit find() schon die Zielposition gefunden und mußt nur noch unterscheiden, ob sie gültig ist:
pos = find(reverse_iterator(iStart),m_list.rend(),...); if(pos!=m_list.rend()) { //gefunden list<...>::iterator tmp = pos.base();//physische Position des gefundenen Iterators --tmp; //umrechnen auf logische Position return tmp; } else { return m_list.end(); }(die Suche nach hinten ist da einfacher:
return find(iStart,m_list.end(),...);)