wie kann ich eine Memberfunktion eines Objekts (welches einer Funktion
als Pointer �bergeben wurde) als Pr�dikatfunktion eines STL -Aufrufs
verwenden?
Beispiel
struct S {...};
class A {
//...
bool filter(S s) {...}
};
void fn(A* obj)
{
vector <S> v1,v2;
// Die folgende Zeile kompiliert nicht wg. obj->filter
remove_copy_if ( v1.begin( ), v1.end( ), v2.begin( ), obj->filter);
}
Viele Gr��e
Joachim
"Joachim Puhr" <jpuhr_re...@gmx.de> writes:
> wie kann ich eine Memberfunktion eines Objekts (welches einer Funktion
> als Pointer ᅵbergeben wurde) als Prᅵdikatfunktion eines STL -Aufrufs
> verwenden?
schaue dir mal das Template mem_fun aus <functional> an.
Viele Grᅵᅵe
Sebastian Waschik
std::remove_copy_if(v1.begin(), v1.end(),
std::back_inserter(v2),
// oder v2.begin(), wenn schon genug Platz in v2 ist
std::bind1st(std::mem_fun(&A::filter), obj));
> }
MfG
Falk
Lars
Eventuell ist statt v2.begin() ein std::back_inserter(v2) sinnvoller
(siehe <iterator> Header). Ansonsten läufst Du Gefahr, über das Ende
hinaus zu schreiben.
Das Prädikat müsstest Du über std::mem_fun und std::bind1st
hinbekommen:
std::bind1st(std::mem_fun(&A::filter),&obj)
(siehe <functional> Header)
Mit std::tr1::bind bzw boost::bind geht das auch noch einfacher:
bind(&A::filter,&obj,_1);
Gruß,
SG
Eine nichtstatische Elementfunktion kann nicht unmittelbar als Prädikat für
einen STL-Algorithmus benutzt werden.
Die einfachste Lösung wäre, A::filter static zu machen, falls das möglich
ist.
Wenn das nicht geht, da A::filter Daten aus dem zugehörigen Objekt braucht,
musst du ein Funktionsobjekt benutzen, also eine Klasse, die eine passende
Elementfunktion operator() (S &) enthält. Im folgenden (ungetesteten!)
Beispiel habe ich das Funktionsobjekt in die Klasse A geschachtelt, damit
der obige Aufruf mit obj->filter weiterhin funktioniert:
class A
{
public:
class TheFilter
{
public:
bool operator() (const S &s) const // ggf. auch ohne const
{
// investigate s --> bool result
return result;
}
} filter;
};
Wahrscheinlich musst du A::TheFilter noch mit passenden Konstruktoren
ausrüsten, da sie keinen direkten Zugriff auf die anderen Elemente von A
hat, solange du kein friend benutzt. Ich persönlich vermeide friend, da es
die Kapselung untergräbt und weiß daher nicht, ob das hier sinnvoll sein
könnte.
Natürlich kannst du TheFilter auch gleich komplett außerhalb von A
definieren und im Konstruktor einen Zeiger oder eine Referenz auf A
übergeben. Dann müsstest du oben anstelle von obj->filter so etwas wie
TheFilter(obj) an remove_copy_if übergeben und einen passenden Konstuktor
bereitstellen.
Gruß
Björn
Joachim Puhr schrieb:
> wie kann ich eine Memberfunktion eines Objekts (welches einer Funktion
> als Pointer ᅵbergeben wurde) als Prᅵdikatfunktion eines STL -Aufrufs
> verwenden?
> Beispiel
> struct S {...};
> class A {
> //...
> bool filter(S s) {...}
> };
>
> void fn(A* obj)
> {
> vector <S> v1,v2;
> // Die folgende Zeile kompiliert nicht wg. obj->filter
> remove_copy_if ( v1.begin( ), v1.end( ), v2.begin( ), obj->filter);
> }
// wenn TR1 nicht vefᅵgbar ist:
//#include <boost/tr1/functional>
#include <functional>
//...
void fn(A* obj)
{
//...
remove_copy_if (v1.begin(), v1.end(), v2.begin(),
std::tr1::bind(&A::filter, obj, std::tr1::placeholders::_1));
}
Das sollte es tun. Den Adress-Operator kannst Du AFAIK auch bei jedem
aktuellen Compiler weglassen. Und beachte die kleinen Fallstricke am
Rande: obiges geht nur so einfach, weil obj ein Pointer ist. Informiere
Dich also auch ᅵber std::tr1::ref.
MfG
Olaf Krzikalla
Das habe ich schonmal probiert und aus Interesse gerade nocheinmal. Ohne
boost habe ich es bisher nie hinbekommen. Das Problem ist, das eine
stl-algorithm-funktion wohl nur zul�sst, auch mit STL-binder, das eine
Elementfunktion oder ein Funktor verwendet wird. Wenn es noch anders geht,
ohne boost, dann m�chte ich das auch wissen.
So geht es:
#include "boost/functional.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
struct S
{
public:
S () : x(-1) {}
S (int x_in) :x(x_in){}
int x;
};
class A
{
int b;
public:
bool filter(S s)
{
return s.x > 9;
}
};
int main()
{
using namespace std;
using namespace boost::lambda;
A * obj = new A;
std::vector<S> v1,v2(10);
v1.push_back(S(12));
v1.push_back(S(1));
v1.push_back(S(6));
std::remove_copy_if(v1.begin(), v1.end(), v2.begin(), bind(&A::filter, obj,
_1));
[...]
"Joachim Puhr" <jpuhr_re...@gmx.de> schrieb im Newsbeitrag
news:4a7717b4$0$31866$9b4e...@newsspool3.arcor-online.net...
Joachim