find() mit std::vector<boost::function<void()> >
-
#include <vector> #include <boost/function.hpp> void Foo() {} void Bar() {} int main() { typedef std::vector<boost::function<void()> > VectorType; VectorType v; v.push_back(Foo); v.push_back(Bar); boost::function<void()> f = Foo; VectorType::iterator it = find(v.begin(), v.end(), f); assert(it != v.end()); v.erase(it); }Ich möchte ein weiteres boost::function-Objekt in dem vector suchen, um es daraus zu entfernen. Doch ich erhalte schöne viele Fehlermeldungen:
error: ambiguous overload for 'operator==' in '(&__first)->__gnu_cxx::__normal_ iterator<_Iterator, _Container>::operator* [with _Iterator = boost::function<void ()(), std::a... (gekürzte Fassung)Auf der boost-Seite steht etwas zum Thema vergleichen von zwei function-Objekten, ich benötige die Funktion boost::function_equal, doch wie kann ich die einbauen in find()???
mfg.
-
müßte doch mit 'nem Functor gehen
struct FuncEqual { typedef boost::function<void()> BoostFunc; FuncEqual( BoostFunc& theFunc ) : m_Func(theFunc){} bool operator()( const BoostFunc& check )const { return function_equal(m_Func, check); } BoostFunc& m_Func; };
-
Scheiße, ich komm einfach nicht weiter. ich hab das jetzt eingebaut doch es klappt immer noch net:
#include <vector> #include <boost/function.hpp> void Foo() {} void Bar() {} struct FuncEqual { typedef boost::function<void()> BoostFunc; FuncEqual( BoostFunc& theFunc ) : m_Func(theFunc){} bool operator()( const BoostFunc& check )const { return boost::function_equal(m_Func, check); } BoostFunc& m_Func; }; int main() { typedef std::vector<boost::function<void()> > VectorType; VectorType v; v.push_back(Foo); v.push_back(Bar); boost::function<void()> f = Foo; VectorType::iterator it = find_if(v.begin(), v.end(), f, FuncEqual); assert(it != v.end()); v.erase(it); }Fehlermeldungen:
main5.cpp: In function `int main()': main5.cpp:27: error: expected primary-expression before ')' token C:/Boost/include/boost-1_33_1/boost/function_equal.hpp: In function `bool boost::function_equal_impl(const F&, const G&, long int) [with F = boost::function<void ()(), std::allocator<void> >, G = boost::function<void ()(), std::allocator<void> >]': C:/Boost/include/boost-1_33_1/boost/function_equal.hpp:24: instantiated from `bool boost::function_equal(const F&, const G&) [with F = boost::function<void ()(), std::allocator<void> >, G = boost::function<void ()(), std::allocator<void> >]' main5.cpp:13: instantiated from here C:/Boost/include/boost-1_33_1/boost/function_equal.hpp:17: error: ambiguous overload for 'operator==' in 'f == g' C:/Boost/include/boost-1_33_1/boost/function_equal.hpp:17: note: candidates are: operator==(void (boost::function0<void, std::allocator<void> >::dummy::*)(), void (boost::function0<void, std::allocator<void> >::dummy::*)()) <built-in> C:/Boost/include/boost-1_33_1/boost/function/function_base.hpp:601: note: typename boost::enable_if_c< boost::type_traits::ice_not< boost::is_integral<T>::value>::value, bool>::type boost::operator==(const boost::function_base&, Functor) [with Functor = boost::function<void ()(), std::allocator<void> >] C:/Boost/include/boost-1_33_1/boost/function/function_base.hpp:610: note: typename boost::enable_if_c< boost::type_traits::ice_not< boost::is_integral<T>::value>::value, bool>::type boost::operator==(Functor, const boost::function_base&) [with Functor = boost::function<void ()(), std::allocator<void> >] C:/Boost/include/boost-1_33_1/boost/function/function_template.hpp:590: note: void boost::operator==(const boost::function0<R, Allocator>&, const boost::function0<R, Allocator>&) [with R = void, Allocator = std::allocator<void>]Jetzt versteh ich gar nichts mehr

-
find_if(v.begin(), v.end(), FuncEqual(f) );Sry, wollte ich noch dazu-editieren, darf ich ja aber unregistriert nicht..
-
Ne, das klappt auch nicht, die fetten Fehler treten ja schon bei der Klasse auf. (Zeile 13)
mfg.
-
Das Problem liegt eigentlich sogar schon dort, dass ich nichtmal 2 boost::function-Objekte mit dem operator== vergleichen kann, obwohl dies in der Doku so beschrieben wird.
#include <iostream> #include <boost/function.hpp> int main() { boost::function<void()> f1; boost::function<void()> f2; std::cout << (f1 == f2); }main5.cpp:12: error: ambiguous overload for 'operator==' in 'f1 == f2'Ich hoffe ihr könnt mir helfen, ich bin am verzweifeln!?
mfg.
-
boost::signals
-
...... schrieb:
boost::signals
Das Problem ist nur, das dieser Vektor aus Funktionszeigern nochmal in einer Map liegt. boost::signals geht da leider net, das es ja noncopyable ist

mfg.
-
Ich hab's jetzt doch mit boost::signal gemacht und als Value nen boost::share_ptr<boost::signal<void()> > genommen. War nen bisschen aufwändiger, aber jetzt klappt's. Mich wundert's aber immernoch warum das mit den operator== von den boost::functions nicht geklappt hat...
mfg.
PS: Danke nochmal für den Tipp mit signal, scheint echt praktisch zu sein die Klasse.
-
Ich konnte es nicht glauben und habe es selbst getestet und ich bekomme kein Programm zum laufen, das zwei boost::functions (boost::function< void() > in meinem Fall) vergleicht, da op== mehrdeutig ist.
Kann jemand ein funktionsfähiges Beispiel liefern, das op== verwendet _und_ kompilierbar ist?
-
joomoo schrieb:
Das Problem liegt eigentlich sogar schon dort, dass ich nichtmal 2 boost::function-Objekte mit dem operator== vergleichen kann, obwohl dies in der Doku so beschrieben wird.
Wo wird das beschrieben? Soweit ich weiß kann man nur Funktionen/Funktionsobjekte mit Function-Wrappern vergleichen.
Sprich:
OK:void f(); boost::function<void()> fr = f; assert(fr == f);Geht nicht:
void f(); boost::function<void()> fr = f; boost::function<void()> fr2 = f; assert(fr == fr2);Dein find_if-Code könnte somit so aussehen (ungetestet):
void f() {} void g() {} template <class T> struct FnEq { FnEq(T f) : f_(f) {} template <class FnRef> bool operator()(const FnRef& f) const { return f == f_; } T f_; }; template <class T> FnEq<T> fnEq(T f) { return FnEq<T>(f); } int main() { typedef std::vector<boost::function<void()> > Funcs; Funcs funcs; funcs.push_back(f); funcs.push_back(g); Funcs::iterator it = std::find_if(funcs.begin(), funcs.end(), fnEq(f)); assert(it != funcs.end()); }
-
Stimmt hast recht, ich hab mich verlesen. Aber warum kann man nicht zwei boost::function-Objekte vergleichen? Ist doch voll wichtig, oder nicht?
mfg.
-
joomoo schrieb:
Stimmt hast recht, ich hab mich verlesen. Aber warum kann man nicht zwei boost::function-Objekte vergleichen?
Das ist übrigens eines boost::function FAQ. Die Antwort findest du hier:
http://www.boost.org/doc/html/function/faq.html#id2699084
-
Ich weiß nicht ... ich finde die FAQ sehr komisch. Also ich würde zumindest eine andere Semantik erwarten. Was interessieren mich die Typen? Ich erwarte Gleichheit, wenn die beiden Funktionen die selbe Funktion referenzieren. Im Prinzip wäre schon ein Adressvergleich des Funktionszeigers hilfreich. Natürlich ist auch das problematisch, wenn wir ein Funktions/objekt/ verwenden, welches keinen operator== implementiert. Aber dann wäre die Begründung eine ganz andere und ich denke selbst hier könnte man mit RTTI evtl. noch einen Vergleich zustande bekommen. Vielleicht auch nicht. Na ja ...
[EDIT]
Uh ... ok, vergesst das. Ich habe mich verlesen. Die FAQ ist OK.
-
HumeSikkins schrieb:
joomoo schrieb:
Stimmt hast recht, ich hab mich verlesen. Aber warum kann man nicht zwei boost::function-Objekte vergleichen?
Das ist übrigens eines boost::function FAQ. Die Antwort findest du hier:
http://www.boost.org/doc/html/function/faq.html#id2699084Danke für den Link. Ich weiß nun auch, dass man boost::signal nehmen muss fürn std::vector<boost::function<...> >.
mfg.