C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Class Funktion Ptr. mit <functional> usw.

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Mario Schunda
Guest





PostPosted: Wed Feb 16, 2005 11:03 pm    Post subject: Class Funktion Ptr. mit <functional> usw. Reply with quote



Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern auf
Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer anderen
Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine einfache
Function hat keine Probleme gemacht. Wie geht es aber mit einer Funktion in
einer Classe?

Boost oder andere Libs kommen leider nicht in frage.

Kann mir jemand Helfen. Schönen Dank in voraus.

Mario

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Martin Kaul
Guest





PostPosted: Fri Feb 18, 2005 10:03 am    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote



Mario Schunda wrote:
Quote:
struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine einfache
Function hat keine Probleme gemacht. Wie geht es aber mit einer Funktion in
einer Classe?

Was spricht gegen operator() in der Klasse cElementWorker ?

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
bool operator()( const stElement &Element )
{
return isZero(Element);
}
};


und dann

remove_if( Ele.begin(), Ele.end(), cElementWorker() );


Oder du schreibst ne eigene Predicat Klasse

template< class C, typename V >
class mem_fun_ptr
{
public:
typedef V value_type;
typedef C class_type;
typedef bool ( class_type:: *MemberFunction_T )( const value_type & );

private:
class_type &reference_;
MemberFunction_T function_;

public:
mem_fun_ptr( class_type &reference,
MemberFunction_T function )
: reference_ ( reference )
, function_ ( function )
{
}
bool operator()( const value_type &value )
{
return (reference_.*function_)( value );
}
};

und verwendest sie:

remove_if( Ele.begin(), Ele.end(),
mem_fun_ptr<cElementWorker, stElement>
(Ew, &cElementWorker::isZero) );


tschaule
Martin

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Fri Feb 18, 2005 10:46 am    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote



Mario Schunda wrote:

Quote:
Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern
auf Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer
anderen Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine
einfache Function hat keine Probleme gemacht. Wie geht es aber mit einer
Funktion in einer Classe?

Du brauchst std::bind1st und std::mem_fun_ref:

remove_if(Ele.begin(), Ele.end(),
bind1st(mem_fun_ref(&cElementWorker::isZero), Ew);

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Falk Tannhäuser
Guest





PostPosted: Fri Feb 18, 2005 3:17 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:

Quote:
struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Am einfachsten wäre es wohl, der Klasse cElementWorker
(anstelle der Funktion isZero() oder zusätzlich) den Operator

bool operator()(stElement const& Element) const
{
return Element.x == 0;
}

zu verpassen - damit kann man dann einfach
std::remove_if(Ele.begin(), Ele.end(), cElementWorker());
aufrufen.
Will man diese Klasse nicht verändern, braucht man ne
neue Hilfsklasse:

struct Call_cElementWorker_isZero
{
cElementWorker const& ew;
Call_cElementWorker_isZero(cElementWorker const& e) : ew(e) {}
bool operator()(stElement const& elt) const { return ew.isZero(elt); }
};

Damit geht dann
std::remove_if(Ele.begin(),
Ele.end(),
Call_cElementWorker_isZero(Ew));

Wenn man solche Hilfsklässchen häufig für verschiedene Element-
klassen und/oder Memberfunktionen braucht, könnte man eventuell
darüber nachdenken, das ganze zu templatisieren...

MfG
Falk

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andreas Profous
Guest





PostPosted: Fri Feb 18, 2005 4:38 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:

Quote:

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}


guck dir mal boost bind oder für komplexere Sachen lambda an:
http://www.boost.org/libs/bind/bind.html

aus dem Bauch heraus würd ich schreiben:
remove_if(Ele.begin(), Ele.end(), bind(&cElementWorker::isZero, _1));
(und evtl. erase() aufrufen)

HTH
Andreas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Maeder
Guest





PostPosted: Fri Feb 18, 2005 6:18 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda <weg_mario (AT) familie-schunda (DOT) de> writes:

Quote:
struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}

Diese Funktion sollte const sein. Und die Implementation ist etwas wortgewaltig für meinen Geschmack:


bool isZero(const stElement &Element) const
{
return Element.x == 0;
}

tut's doch auch, oder?


Quote:
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Das Problem ist, dass <functional> Funktionen, die ihr Argument per
Referenz übernehmen, nicht unterstützt.

std::remove_if(Ele.begin(),Ele.end(),
std::bind1st(std::mem_fun(&cElementWorker::isZero),&Ew));

Zum auf der Hand liegenden sagt gcc 3.4.3 sehr instruktiv:

/usr/local/gcc/3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/../../../../include/c++/3.4.3/bits/stl_function.h:406: error: forming reference to reference type `const stElement&'


Es wird ein Template mit T==stElement const & instantiiert, welches
den Typ T const & verwenden will, und das ist laut dem ISO
C++-Standard nicht korrekt, weil da ein Referenztyp basierend auf
einem Referenztyp gebildet werden soll.


Als Ausweg kannst Du

- den Argumenttyp von isZero auf stElement ändern; das ist keine
allgemeine Lösung, aber in diesem Fall, wo stElement so klein ist,
wohl gangbar

- die functional-Bibliothek von Boost (http://www.boost.org/) verwenden

#include <boost/functional.hpp>

....

std::remove_if(Ele.begin(),Ele.end(),
boost::bind1st(boost::mem_fun(&cElementWorker::isZero),&Ew));


Quote:
Boost oder andere Libs kommen leider nicht in frage.

Warum nicht?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stefan Reuther
Guest





PostPosted: Fri Feb 18, 2005 6:55 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:
Quote:
Ziel ist es, alle Elemente eines Containers, einer Funktion in einer anderen
Classe zu übergeben.
[...]
remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine einfache
Function hat keine Probleme gemacht. Wie geht es aber mit einer Funktion in
einer Classe?

Da scheint es in der Standardbibliothek nichts zu geben.

Quote:
Boost oder andere Libs kommen leider nicht in frage.

Warum nicht?

Du kannst es dir natürlich leicht nachbauen:
----8<--------8<--------8<--------8<--------8<--------8<----
template class bind_mf_t {
T& t;
RV (T::*f)(A);
public:
bind_mf_t(T& t, RV (T::*f)(A))
: t(t), f(f) { }
RV operator()(A a)
{ return (t.*f)(a); }
};

template<typename T, typename RV, typename A>
bind_mf_t<T,RV,A>
bind_mf(T& t, RV (T::*f)(A))
{
return bind_mf_t<T,RV,A>(t,f);
}

void foo()
{
std::list<stElement> Ele;
cElementWorker Ew;

std::remove_if(Ele.begin(),
Ele.end(),
bind_mf(Ew, &cElementWorker::isZero));
}
----8<--------8<--------8<--------8<--------8<--------8<----
(ungetested, aber immerhin compiliert)


Stefan

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Mario Schunda
Guest





PostPosted: Fri Feb 18, 2005 10:31 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:

Quote:
Hi NG

Hat sich schon erledigt.

Mario

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Albrecht Fritzsche
Guest





PostPosted: Fri Feb 18, 2005 11:25 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:
Quote:
Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern auf
Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer anderen
Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine einfache
Function hat keine Probleme gemacht. Wie geht es aber mit einer Funktion in
einer Classe?

Boost oder andere Libs kommen leider nicht in frage.

Kann mir jemand Helfen. Schönen Dank in voraus.

Wenn Du den IMHO ueberfluessigen cElementWorker durch

struct IsZero {
bool operator()(const stElement& Element)
{ return Element.x == 0 ? true : false; }
};

ersetzt, funktioniert ein

vector<stElement>::iterator new_end =
remove_if(Ele.begin(), Ele.end(), IsZero());

prima.

Ali

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Nicolas Pavlidis
Guest





PostPosted: Sat Feb 19, 2005 12:43 am    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Mario Schunda wrote:
Quote:
Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern auf
Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer anderen
Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;

// da reicht ein eifnaches return(Element.x) Wink
SCNR

Quote:
}
};

void foo()
{
list<stElement> Ele;
cElementWorker Ew;

remove_if(Ele.begin(),
Ele.end(),
"Hier muss 'isZero' in Var. Ew angesprungen werdn");
}

Beim remove_if Scheitert es. Es ist nur ein Beispiel. Es geht um den
Predicat der bei Diversen Fuktionen der std gebraucht werden.
Mit einer Extra Classe auf Basis unary_function geht es. Auch eine einfache
Function hat keine Probleme gemacht. Wie geht es aber mit einer Funktion in
einer Classe?

2 Moeglichkeiten wuerden mir einfallen:
1) Geht es dass du die Methode isZero statisch machst?
2) Implemntiere einfach den opaerto() fuer die classe:

class cElementWorker
{
public:
bool operator()(const stElement &Element)
{
return(Element.x)
}
};

Das solte dann mit den STL - Algorithmen / Functoren (bzw
Funktionsobjekten) gehen.

Das problem ist, dass isZero in deinem Fall eine Memberfunction ist, und
man dafuer einen Funktionspointer auf eine Memberfunktion braucht ein
Objekt der Klasse um aufgerufen werden zu koennen.

Die ganzen Algorithmen der STL beruecksichtigen diesen mechanismus den
C++ bietet AFAIK leider nicht, daher geht es so wie du willst IMHO
nicht, aber eine der beiden Moeglichkeiten die ich gesagt habe ist
hoffentlich umsetzbar.

HTH && LG
Nicolas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Sun Feb 20, 2005 3:55 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Nicolas Pavlidis wrote:

Quote:
Mario Schunda wrote:
Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern
auf Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer
anderen Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;

// da reicht ein eifnaches return(Element.x) Wink
SCNR

Wenn du schon nicht "resisten conntest", dann mach's wenigstens richtig. Die
Klammern werden nicht benötigt, dafür fehlt aber ein "!" und ein ";".

Quote:
Das problem ist, dass isZero in deinem Fall eine Memberfunction ist, und
man dafuer einen Funktionspointer auf eine Memberfunktion braucht ein
Objekt der Klasse um aufgerufen werden zu koennen.

Die ganzen Algorithmen der STL beruecksichtigen diesen mechanismus den
C++ bietet AFAIK leider nicht,

Was ist mit mem_fun und mem_fun_ref?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Nicolas Pavlidis
Guest





PostPosted: Tue Feb 22, 2005 1:34 pm    Post subject: Re: Class Funktion Ptr. mit <functional> usw. Reply with quote

Rolf Magnus <ramagnus (AT) t-online (DOT) de> writes:

Quote:
Nicolas Pavlidis wrote:

Mario Schunda wrote:
Hi NG

Also die Header <functional> und <algorithm> in Verbindung mit Pointern
auf Classen-Funktionen rauben mir noch den letzten Nerv.

Ziel ist es, alle Elemente eines Containers, einer Funktion in einer
anderen Classe zu übergeben.

struct stElement
{
int x;
};

class cElementWorker
{
public:
bool isZero(const stElement &Element)
{
return Element.x == 0 ? true : false;

// da reicht ein eifnaches return(Element.x) Wink
SCNR

Wenn du schon nicht "resisten conntest", dann mach's wenigstens richtig. Die
Klammern werden nicht benötigt, dafür fehlt aber ein "!" und ein ";".

Sorry, habs zui spaet bemerkt.

Quote:
Das problem ist, dass isZero in deinem Fall eine Memberfunction ist, und
man dafuer einen Funktionspointer auf eine Memberfunktion braucht ein
Objekt der Klasse um aufgerufen werden zu koennen.

Die ganzen Algorithmen der STL beruecksichtigen diesen mechanismus den
C++ bietet AFAIK leider nicht,

Was ist mit mem_fun und mem_fun_ref?

Deshalb auch AFAIK Smile. Nein, diese beiden Dinge hab ich nicht gekannt,
wieder was gelernt Smile.

LG
Nicolas
--
Quote:
Nicolas Pavlidis | Elvis Presly: | |__ |
Student of SE & KM | "Into the goto" | |__| |
[email]pavnic (AT) sbox (DOT) tugraz.at[/email] | ICQ #320057056 | |
-------------------University of Technology, Graz----------------|

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.