[for_each] bei containern mit pointer-objekten
-
ich hatte das schon in einem anderen thread gefragt, aber leider bisher keine Antwort erhalten. Kann man for_each auch bei containern mit pointern anwenden OHNE prädikate zu erstellen?
class bar{ public: bar() {} virtual void foo1() = 0; virtual void foo2() { std::cout << "bar::foo2" << std::endl; } }; class bar2 : public bar{ public: bar2() {} void foo1() { std::cout << "bar2::foo1" << std::endl; } void foo2() { std::cout << "bar2::foo2" << std::endl; } }; class bar3 : public bar{ public: bar3() {} void foo1() { std::cout << "bar3::foo1" << std::endl; } void foo2() { std::cout << "bar3::foo2" << std::endl; } }; int main() { std::vector<bar2> data1(4); std::for_each(data1.begin(), data1.end(), std::mem_fun(&bar::foo1)); std::vector<bar*> data2; data2.push_back(new bar2); data2.push_back(new bar2); data2.push_back(new bar2); data2.push_back(new bar3); /* for_each => Algorithm | Iterator */ //wie sähe hier der for_each Befehl aus? einmal für foo1 und einmal für foo2 std::for_each( data2.begin(), data2.end(), ??? ); }
-
Hi,
wenn du normale Objekte in deinem Container hast, benutzt du mem_fun_ref:
std::vector<bar2> data1(4); std::for_each(data1.begin(), data1.end(), std::mem_fun_ref(&bar::foo1));Bei Pointern im Container mem_fun:
std::vector<bar*> data2; std::for_each( data2.begin(), data2.end(), std::mem_fun(&bar::foo1) );
-
super danke!
hatte das ähnlich getestet... das mit std::mem_fun_ref hatte ich falsch.okay. und nun die nächste frage:
wie kann man referenzen übergeben:struct bar{ void foo() {} void fooCbv(int& i) {} void fooRef(int& i) {} } std::vector< bar > data1(10); int i=0; for_each(data1.begin(), data1.end(),std::mem_fun_ref(&bar::foo) ); //wuppt for_each(data1.begin(), data1.end(),std::bind2nd( std::mem_fun_ref(&bar::fooCbv), i) ); //wuppt for_each(data1.begin(), data1.end(),std::bind2nd( std::mem_fun_ref(&bar::fooRef), i) ); // ERRORERROR:
functional(312) : warning C4181: qualifier applied to reference type
with _Fn2=std::mem_fun1_ref_t<void,bar,int &>Muss man da auch das i mit irgend einem Funktional binden?
-
Hmmm, das müsste auch normal funktionieren, aber irgendwas war da mal mit nem Reference-Problem bei sowas.
Mit boost::bind und boost::mem_fn funktionierts jedenfalls ganz normal und find ich auch so schöner, wenn dir boost zur Verfügung steht, würd ichs benutzen:
struct bar{ void foo() {} void fooCbv(int i) {} // Dein Copy-by-Value hatte auch nen & ;) void fooRef(int& i) {} }; int main() { using namespace boost; std::vector< bar > data1(10); int i=0; for_each(data1.begin(), data1.end(), boost::mem_fn(&bar::foo) ); for_each(data1.begin(), data1.end(), boost::bind( boost::mem_fn(&bar::fooCbv), _1, i) ); for_each(data1.begin(), data1.end(), boost::bind( boost::mem_fn(&bar::fooRef), _1, i) ); }
-
Erstens: Mem_fn braucht man dann auch nicht mehr wirklich.
Zweitens: Es gibt in der Boost-Bibliothek auch einen Wrapper für Referenzen.
Drittens: Das ganze ist seit TR1 auch ein ISO-Standard.struct bar{ void foo() {} void fooCbv(int i) {} // Dein Copy-by-Value hatte auch nen & ;) void fooRef(int& i) {} }; int main() { using namespace boost; std::vector< bar > data1(10); int i=0; for_each(data1.begin(), data1.end(), std::tr1::bind( &bar::foo, _1 ) ); for_each(data1.begin(), data1.end(), std::tr1::bind( &bar::fooCbv, _1, i ) ); for_each(data1.begin(), data1.end(), std::tr1::bind( &bar::fooRef, _1, std::tr1::ref( i ) ) ); }
-
Das sieht ja noch besser aus. TR1 ist bei mir irgendwie in Vergessenheit geraten und da das tr1::bind ohne nen mem_fn sieht für mich ziemlich ungewöhnlich aus ...
-
KasF schrieb:
Das sieht ja noch besser aus. TR1 ist bei mir irgendwie in Vergessenheit geraten und da das tr1::bind ohne nen mem_fn sieht für mich ziemlich ungewöhnlich aus ...
Gut, dass es immer mehrere Wege zum Ziel gibt - für mich hat boost::bind mit mem_fn auf den ersten Blick ungewöhnlich ausgesehen, da ich beim Kennenlernen von boost direkt ohne gelernt habe zu arbeiten (nach http://boost.org/libs/bind/bind.html#with_member_pointers)

-
danke für die antworten... tr1 gefällt mir auch am besten, aber auf unserem linux cluster bekommen die admins leider gcc4.x nicht zum laufen und der gcc3.4 unterstützt kein tr1. boost verwende ich dort zwar, aber nicht für alle konfigurationen!
aber es hilft mir dennoch weiter