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                             ]