Boost PTR Container und Algorithmen
-
Okay danke für die Tipps.
Jetzt fällt mir natürlich bei find_if auf das die Prädikats-Funktion nur einen Parameter übernimmt (das entsprechende Element aus dem Container jeweils). Im Internet gibt es viele Beispiele wo find_if auf einen Konstanten Wert überprüft, nun ist es bei mir aber so das ich auf einen Variablen Wert überprüfen möchte - ist es irgendwie möglich einen 2. Parameter einzuführen?(ich habe gesehen das es in einigen Beispielen [z.b. http://www.willemer.de/informatik/cpp/stl.htm bei Funktionsobjekten] nicht mit einer Einfachen Funktion sondern mit einer Klasse gearbeitet wurde - klinkt logisch aber da geht die Übersichtlichkeit des find_if doch sehr verloren)
-
FunMaker schrieb:
(ich habe gesehen das es in einigen Beispielen [z.b. http://www.willemer.de/informatik/cpp/stl.htm bei Funktionsobjekten] nicht mit einer Einfachen Funktion sondern mit einer Klasse gearbeitet wurde - klinkt logisch aber da geht die Übersichtlichkeit des find_if doch sehr verloren)
Ja, Funktionsobjekte schmälern die Übersichtlichkeit leider manchmal
Ich lasse das in solchen Fällen meinen Bauch entscheiden..
-
nicht mit einer Einfachen Funktion sondern mit einer Klasse gearbeitet wurde - klinkt logisch aber da geht die Übersichtlichkeit des find_if doch sehr verloren
In wiefern sind den da Funktionen besser?
-
FunMaker schrieb:
Jetzt fällt mir natürlich bei find_if auf das die Prädikats-Funktion nur einen Parameter übernimmt (das entsprechende Element aus dem Container jeweils). Im Internet gibt es viele Beispiele wo find_if auf einen Konstanten Wert überprüft, nun ist es bei mir aber so das ich auf einen Variablen Wert überprüfen möchte - ist es irgendwie möglich einen 2. Parameter einzuführen?
Was für einen variablen Wert willst du denn prüfen? Prädikate sollten allgemein stateless sein, soll heißen das Funktionsobjekt darf z.B. nicht mitzählen wie oft es den Vergleich schon angestellt hat o.ä.
Was aber geht sind Parameter die du den Prädikaten mitgibst und die sich nicht ändern, z.B.:int main() { std::vector<Point3D> p3dVec; FillP3dVec(); //Prädikat: struct CompareXCoords { CompareXCoords(double compareTo) : value(compareTo) {} bool operator()(Point3D const& p3d) { return value == p3d.getX();} private: double value; }; Point3D& xIs0 = *( std::find_if(p3dVec.begin(), p3dVec.end(),CompareXCoords(0.0)) ); Point3D& xIs6 = *( std::find_if(p3dVec.begin(), p3dVec.end(),CompareXCoords(6.0)) ); }Ich find das mit den Funktionsobjekten übrigens meist weniger unübersichtlich als mit Funktionen: Funktionen müssen immer "irgendwo anders" definiert werden, auf jeden Fall außerhalb der Funktion in der ich sie dann an den Algorithmus übergebe. Funktoren hingegen kann ich unmittelbar vor der Benutzung definieren, als local class (vermutlich ein weniger bekanntes Feature in C++).
-
pumuckl schrieb:
Funktoren hingegen kann ich unmittelbar vor der Benutzung definieren, als local class (vermutlich ein weniger bekanntes Feature in C++).
Vermutlich deshalb wenig bekannt weil man es eben nicht machen darf

-
pumuckl schrieb:
Ich find das mit den Funktionsobjekten übrigens meist weniger unübersichtlich als mit Funktionen: Funktionen müssen immer "irgendwo anders" definiert werden, auf jeden Fall außerhalb der Funktion in der ich sie dann an den Algorithmus übergebe.
Übersichtlicher als Funktionen sind Funktionsobjekte meistens schon, aber die Frage ist hier ja, ob "inline-Code" nicht lesbarer/sinnvoller wäre.
So wie ich das verstanden habe, geht's hier um
//Prädikat; edit: auf Wunsch von Lord Jaxom ausgelagert :) struct CompareXCoords { CompareXCoords(double compareTo) : value(compareTo) {} bool operator()(Point3D const& p3d) { return value == p3d.getX();} private: double value; }; Point3D foo() { ... Point3D& xIs0 = *( std::find_if(p3dVec.begin(), p3dVec.end(),CompareXCoords(0.0)) ); return xIs0; }versus
Point3D foo() { ... // Bla-Element finden und zurückgeben BOOST_FOREACH( const Point3D& p, p3dVec ) if ( p.getX() == 0.0 ) return p; }, wo ich persönlich wahrscheinlich die zweite Variante wählen würde.
-
Es sei nochmal darauf hingewiesen, dass erstere Variante überhaupt nicht zulässig ist

-
aber ein
for_each(v.begin(), v.end(), cout<<_1<<endl)
wäre zB ganz niedlich.
-
LordJaxom schrieb:
Es sei nochmal darauf hingewiesen, dass erstere Variante überhaupt nicht zulässig ist

Ist das dann eine MSVC-Erweiterung (mit dem geht's jedenfalls)? Und weil ich ihn grad nicht zur Hand hab: Weiß jemand, wie's mit dem GCC aussieht?
PS: Danke Lord, Shade's Post hatte ich ganz übersehen.
-
Wie Shade bereits angedeutet hat, gibt es ja noch die dritte Variante mit Boost.Lambda.
Point3D foo() { ... Point3D& xIs0 = *( std::find_if(p3dVec.begin(), p3dVec.end(), _1 == 0.0) ); return xIs0; }
-
Badestrand schrieb:
Ist das dann eine MSVC-Erweiterung (mit dem geht's jedenfalls)? Und weil ich ihn grad nicht zur Hand hab: Weiß jemand, wie's mit dem GCC aussieht?
Laut http://www.informit.com/articles/article.aspx?p=345948&seqNum=3 lassen CodeWarrior, DigitalMars, Watcom, Borland und Microsoft das zu. GCC (4.1 und 4.4 getestet) meldet einen Fehler.
-
Don06 schrieb:
Wie Shade bereits angedeutet hat, gibt es ja noch die dritte Variante mit Boost.Lambda.
Richtig, Lambda vergesse ich immer. Das finde ich auch mit Abstand die beste Lösung

LordJaxom schrieb:
Laut http://www.informit.com/articles/article.aspx?p=345948&seqNum=3 lassen CodeWarrior, DigitalMars, Watcom, Borland und Microsoft das zu. GCC (4.1 und 4.4 getestet) meldet einen Fehler.
Schade.. Ich entwickle meistens mit dem MSVC oder GCC, Inkompatibilität ist schon was feines
