Problem mit find_if in std:: list
-
Danke:)
die liste hat bei der erzeugung automatisch ein element, d.h. begin() existiert immer! wenn du das meinst
-
BorisDieKlinge schrieb:
die liste hat bei der erzeugung automatisch ein element, d.h. begin() existiert immer! wenn du das meinst
Ich frage mich gerade auf welches Element der Iterator zeigen muss, wenn zwischen ihm und dem ersten Element (exklusiv!) noch Elemente liegen sollen. Denk da mal drüber nach

-
Nein, ich meinte damit, daß der zu durchsuchende Bereich falsch herum definiert ist - begin() ist der Anfang der list-Daten und den als Ende des durchsuchten Bereiches zu übergeben macht keinen Sinn.
(im günstigsten Fall zeigt iStart auf das zweite Element der Liste und du übergibst letztlich einen leeren Bereich, wahrscheinlicher ist da ein SegFault, weil du entweder vor dem erste Element startest (iStart==begin() - darf nicht dekrementiert werden) oder vom Startpunkt aus über das Listenende hinausrennst.
-
die liste stellt events dar... das erste eventzeitpunkt ist zum zeitpunkt 0 definiert! wo bei da keine events anliegen!
A(0) <- B(5) <- C(8) <- D(9) <- usw.
Buchstanben sind die Elemente, die Zahl in der klammer ist der zweitliche abstand zum element davor! jedes element enthät event am entsprechenden zeitpunkt
Beim start wird das ersteevent-zeitpunkt A(0) ohne events erzeugt. Wenn alle events abgerabeitet wurden, wird automatisch B zum Ersten event! Wie eine ablaufkette
-
kann ich mit find_if nicht rückwärst suchen? ja ich prüfe davor ab ob itStart != begin() ist!
-
Woher soll find_if wissen, dass Du rückwärts suchen willst? Eine Bedingung a la "gehe wahlweise vorwärts oder rückwärts bis it == end" kenne ich nicht

Du hast doch gestern noch nach reverse_iteratoren und so gefragt, ich hatte angenommen, Dir wäre klar, dass die Algorithmen vorwärts (sprich: mit ++) über die Iteratoren gehen.
-
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(),...);)