 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Mario Schunda Guest
|
Posted: Wed Feb 16, 2005 11:03 pm Post subject: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 10:03 am Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 10:46 am Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 3:17 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 4:38 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 6:18 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 6:55 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Fri Feb 18, 2005 10:31 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
Mario Schunda wrote:
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
|
Posted: Fri Feb 18, 2005 11:25 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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
|
Posted: Sat Feb 19, 2005 12:43 am Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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)
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
|
Posted: Sun Feb 20, 2005 3:55 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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)
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
|
Posted: Tue Feb 22, 2005 1:34 pm Post subject: Re: Class Funktion Ptr. mit <functional> usw. |
|
|
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)
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 . Nein, diese beiden Dinge hab ich nicht gekannt,
wieder was gelernt .
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 |
|
 |
|
|
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
|
|