for_each für Memberfunktionen?
-
Edit: Sorry, hatte überlesen, dass es sich um Memberfunktionen handelt.
-
Da hilft dir entweder std::tr1::bind oder, wenn du keine TR1-Stdlib hast mit std::mem_fun und std::bind1st:
std::for_each(vec.begin(), vec.end(), std::tr1::bind(&B::fkt2, this)); //oder std::for_each(vec.begin(), vec.end(), std::bind1st(std::mem_fun(&B::fkt2), *this));
-
@.filmor,
Ich kenne mich mit dem std::tr1::bind nicht so genau aus, aber ich dachte, es wäre dem von Boost ähnlich bis gleich. Dann fehlt bei deinem Code nämlich noch was, denn mit Boost, geht es so:std::for_each(vec.begin(), vec.end(), boost::bind(&B::fkt2, this, _1));Eine weitere Alternative gibt es auch noch:
void B::fkt1() { struct CallFkt2 { B* b; void operator ()(A& a) const { b->fkt2(a); }; }; CallFkt2 temp; temp.b = this; std::for_each(vec.begin(), vec.end(), temp); }Grüssli
-
/edit: hatte was überlesen
-
std::for_each(vec.begin(), vec.end(), std::bind1st(std::mem_fun(&B::fkt2), *this));Das wäre eigentlich das gewesen, was ich gesucht habe, kompiliert aber leider nicht bei mir.
Muss ich ausser algorithm und functional vielleicht noch irgendwelche Header einbinden?
Ich bekomme leider eine riesen Fehlermeldung (DependencyGraph ist hier meine Klasse B und dgNode ist A).
/usr/include/c++/4.2/bits/stl_function.h: In instantiation of ‘std::binder1st<std::mem_fun1_t<void, DependencyGraph, dgNode&> >’: /src/DependencyGraph/DependencyGraph.cpp:164: instantiated from here /usr/include/c++/4.2/bits/stl_function.h:405: error: forming reference to reference type ‘dgNode&’ /usr/include/c++/4.2/bits/stl_function.h:411: error: forming reference to reference type ‘dgNode&’ /usr/include/c++/4.2/bits/stl_function.h: In function ‘std::binder1st<_Operation> std::bind1st(const _Operation&, const _Tp&) [with _Operation = std::mem_fun1_t<void, DependencyGraph, dgNode&>, _Tp = DependencyGraph]’: /src/DependencyGraph/DependencyGraph.cpp:164: instantiated from here /usr/include/c++/4.2/bits/stl_function.h:421: error: invalid cast from type ‘const DependencyGraph’ to type ‘DependencyGraph*’ /usr/include/c++/4.2/bits/stl_algo.h: In function ‘_Function std::for_each(_InputIterator, _InputIterator, _Function) [with _InputIterator = __gnu_cxx::__normal_iterator<dgNode*, std::vector<dgNode, std::allocator<dgNode> > >, _Function = std::binder1st<std::mem_fun1_t<void, DependencyGraph, dgNode&> >]’: /src/DependencyGraph/DependencyGraph.cpp:164: instantiated from here /usr/include/c++/4.2/bits/stl_algo.h:159: error: no match for call to ‘(std::binder1st<std::mem_fun1_t<void, DependencyGraph, dgNode&> >) (dgNode&)’Irgendwie habe ich das Gefühl, dass wenn der Aufruf von for_each derart kompliziert ist, dass eine Schleife vielleicht doch das elegantere Mittel ist. Schade eigentlich.
-
Dravere schrieb:
@.filmor,
Ich kenne mich mit dem std::tr1::bind nicht so genau aus, aber ich dachte, es wäre dem von Boost ähnlich bis gleich. Dann fehlt bei deinem Code nämlich noch was, denn mit Boost, geht es so:std::for_each(vec.begin(), vec.end(), boost::bind(&B::fkt2, this, _1));Tatsache. War das schon immer so? Dann hatte ich wohl einfach Glück mit meinem Code

Jiddoo schrieb:
std::for_each(vec.begin(), vec.end(), std::bind1st(std::mem_fun(&B::fkt2), *this));Das wäre eigentlich das gewesen, was ich gesucht habe, kompiliert aber leider nicht bei mir.
Probier mal
thisstatt*this.
-
.filmor schrieb:
Dravere schrieb:
@.filmor,
Ich kenne mich mit dem std::tr1::bind nicht so genau aus, aber ich dachte, es wäre dem von Boost ähnlich bis gleich. Dann fehlt bei deinem Code nämlich noch was, denn mit Boost, geht es so:std::for_each(vec.begin(), vec.end(), boost::bind(&B::fkt2, this, _1));Tatsache. War das schon immer so? Dann hatte ich wohl einfach Glück mit meinem Code

Bei boost::bind schon immer (seit ich es kenne, also min. seit boost version 1.33), ja. bei std::tr1::bind nehme ich an wird es auch so sein.
-
@Jiddoo,
std::for_each(vec.begin(), vec.end(), std::bind1st(std::mem_fun(&B::fkt2), this));Wird leider nicht funktionieren, da
B::fkt2einA&erwartet. Es müsste einAsein, also keine Referenz. Der C++ Standard ist in diesen Belangen irgendwie äusserst hässlich.
Für sowas ist wirklich Boost.Bind, std::tr1::bind oder das struct zu empfehlen. Oder du machst es einfach "manuell". Im zukünftigen Standard wird sich dies aber zum Glück ändern.Übrigens ist Boost auch sonst sehr zu empfehlen. Also falls du es noch nicht hast, ruhig mal anschauen

boost::bind(&B::fkt2, this)Ist gleich einer Memberfunktion ohne Parameter.
boost::bind(&B::fkt2, this, _1)Sagt, dass es einen Parameter hat.
boost::bind(&B::fkt2, this, _1, _2)Zwei parameter ... usw.

War so, seit ich mich erinnern kann.
Grüssli
-
std::for_each(vec.begin(), vec.end(), boost::bind(&B::fkt2, this, _1));
Das hat funktioniert.

Mit dem tr1 hab ich es nicht hinbekommen, aber vielleicht habe ich da auch noch was in den Compilersettings falsch gehabt.Boost scheint wirklich unglaublich praktisch zu sein. Wenn ich jetzt noch die Zeit hätte mich da intensiv mit zu beschäftigen...

Vielen Dank an alle.
-
Beim TR1 dürfte ein
using std::tr1::placeholdersim Funktionsrumpf helfen...
-
Jiddoo schrieb:
Boost scheint wirklich unglaublich praktisch zu sein. Wenn ich jetzt noch die Zeit hätte mich da intensiv mit zu beschäftigen...

Ja, Boost bietet unheimlich mächtige Mittel. Ich beschäftige mich auch noch nicht so lange mit den Boost C++ Libraries, aber ich bin immer wieder von neuem erstaunt.
