Topic: Function object - pointer to a function
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/01 Raw View
Ryszard Kabatek wrote:
> For an algorithm I can use a pointer to a function:
>
> typedef double (*pF)();
> void algor(pF f);
>
> This works very well for functions, but not for member functions.
>
> I can use a function object (instead of pF) and make the algorithm
> a function template:
[...]
> What about the size of the executable?
> Some mathematical algorithms are pretty large.
> If I have a lot of FuncObjs, I obtain a very large executable.
There are two ways to write a functor: compile time or run time.
What you wrote is strange combination of both.
Compile time functor: using genericity, STL style, more and
more used
-> can generate lots of code, fast
template <class T, class Func>
T static_apply_twice (T x, const Func& f)
{
return f (f (x));
}
Run time functor: using polyphisme, possible genericity
-> smaller code, slower if the operation is simple,
way to slow if the operation is trivial
template <class T>
class FuncObj {
public:
virtual T operator()(const T&) const = 0;
};
template <class T>
T dynamic_apply_twice (T x, const FuncObj& f)
{
return f (f (x));
}
Note that a FuncObj object can be used with
static_apply_twice because it takes a reference.
The STL takes functors by value, so it can't take
FuncObj derived class (it will atempt to copy a pure
base class), so you have to use an intermediate
object to use polymorphism with the STL. BTW, why
can't STL algorithmes simply take a reference
like static_apply_twice ?
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1997/10/30 Raw View
Ryszard Kabatek <kabatek@chemie.uni-halle.de> wrote in article
<34546B5F.51A9@chemie.uni-halle.de>...
> Hi!
> For an algorithm I can use a pointer to a function:
>
> typedef double (*pF)();
> void algor(pF f);
>
> This works very well for functions, but not for member functions.
>
> I can use a function object (instead of pF) and make the algorithm
> a function template:
>
> class FuncObj {public: double operator()();};
> template <class FuncObj> void algor(FuncObj& f);
>
> This works for functions and for member functions.
>
> What about the size of the executable?
> Some mathematical algorithms are pretty large.
> If I have a lot of FuncObjs, I obtain a very large executable.
If FuncObj has no data members, but simply calls a member function of some
global object then you can do the same thing with a simple function. If
FuncObj has some data members you can reduce code bloat with inheritence:
class vFuncObj{ public: virtual double operator()()=0; };
void valgor(vFuncObj& f);
Actually you can write code to convert the 'template function object'
version to the virtual function version and avoid code bloat (not tested,
but this should be close):
template<class FuncObj> class tVFuncObj: public vFuncObj
{
public:
tVFuncObj(FuncObj& x):obj(x){};
FuncObj& obj;
double operator()(){ return obj(); }
}
template<class FuncObj> void algor(FuncObj f)
{
tVFuncObj<FuncObj> vf(f);
valgor(vf);
}
Your big code is down in valgor. Not much code bloat (each algor<T> is
small). There is some (usually small) performance hit in preparing to call
valgor(), and in using the virtual function mechanism to get at operator().
I hope this helps.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/10/30 Raw View
Ryszard Kabatek wrote:
>
> The pointer casting of a member function to a function is not allowed.
> Why?
> It's a hindrance for the use of C algorithms.
Because a pointer-to-member is a completely different animal
from a pointer. A pointer-to-member is a way of finding a
particular member, given a particular structure. It takes a
binary operator (either .* or ->*) to combine a structure with a
pointer-to-member to get at the member. For data members, you
can think of a pointer-to-member as the offset within the
structure. In other words, a pointer-to-member doesn't really
point to anything at all, until applied to a particular
structure. Therefore, it's meaningless to try to cast a
pointer-to-member to a plain pointer.
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1997/10/30 Raw View
Remember that a member function always has a hidden "this" parameter so
casting a pointer to a function to a pointer to a member function, or
vice versa, will not work too well upon implementation.
Ryszard Kabatek wrote:
[...]
> The pointer casting of a member function to a function is not allowed.
> Why?
> It's a hindrance for the use of C algorithms.
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Ryszard Kabatek <kabatek@chemie.uni-halle.de>
Date: 1997/10/28 Raw View
Hi!
For an algorithm I can use a pointer to a function:
typedef double (*pF)();
void algor(pF f);
This works very well for functions, but not for member functions.
I can use a function object (instead of pF) and make the algorithm
a function template:
class FuncObj {public: double operator()();};
template <class FuncObj> void algor(FuncObj& f);
This works for functions and for member functions.
What about the size of the executable?
Some mathematical algorithms are pretty large.
If I have a lot of FuncObjs, I obtain a very large executable.
The pointer casting of a member function to a function is not allowed.
Why?
It's a hindrance for the use of C algorithms.
class X {public: double f();};
pF pf = X::f; // :(
or pf = (pF)X::f; // :(
By the way, does a new-style cast operator cast a pointer to a function?
--
Ryszard Kabatek
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]