Re: Need help with generic functors....

Discussion in 'C++' started by Rob Williscroft, Aug 17, 2003.

  1. Gordon Scott wrote in
    news:mSC%a.19080$:

    > Hi All,
    >
    > I'm trying to work on a small asynchronous frame work that performs
    > different jobs by having a pool of threads that pull different Task
    > objects off of a queue. I would like to define a Task object that
    > somehow contains different types of functor objects (or function
    > pointers) and parameters for execution. This way I can have one
    > thread pool performing a variety of different operations.
    >
    > I'm having trouble coming up with a way to do this.
    > I would like to do something like:
    >
    > class Foo{
    > void operator()(int param);
    > };
    > class Bar{
    > void operator()(std::string param);
    > }
    >
    > int main(){
    > Foo foo;
    > Bar bar;
    > Task taskA(foo, 1);
    > Task taskB(bar, "Hello World");
    >
    > Scheduler::Schedule(taskA); // add taskA to the task queue
    > Scheduler::Schedule(taskB); // add taskB to the task queue
    > .
    > .
    > .
    > }
    >
    > defining Task like so, obviously doesn't work.


    Then you need another layer of indirection:

    class TaskBase
    {
    virtual void Run() = 0;
    virtual ~TaskBase() {}
    };

    >
    > template<class F, class T>
    > class Task{


    class Task: public TaskBase

    > public:
    > Task(F functor, T parameter){
    > _functor = functor;
    > _parameter = parameter;
    > }
    > void Run(){
    > _functor(_parameter);
    > }
    > private:
    > F _functor;
    > T _parameter;
    > };
    >
    >


    Now add the function Victor showed, but now we know about Scheduler:

    class Scheduler
    {
    // ....

    std::list< TaskBase * > que;

    template<class F, class P>
    void Schedule(F f, P p)
    {
    TaskBase *tb = new Task<F,P>(f,p);
    que.push_back( tb );
    }

    ~Scheduler()
    {
    // ...
    std::list< TaskBase * >::iterator ptr, lim;
    for (ptr = que.begin(), lim = que.end(); ptr != lim; ++ptr)
    {
    delete *ptr;
    }
    }
    };



    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Aug 17, 2003
    #1
    1. Advertising

  2. Rob Williscroft

    Gordon Scott Guest

    Thanks a bunch,

    using your help and these two articles

    http://www.tutok.sk/fastgl/callback.html
    http://www.codeproject.com/cpp/CallbackDemo.asp

    I now have the following that allows me to make functors for calling class
    member functions.
    Are there any major problems with this implementation, or ways to clean up?

    class Task{
    public:
    Task() {}
    virtual void Run()const {};
    virtual ~Task() {}
    };

    template<class Functor, class Parameter>
    class TaskImpl : Task{
    public:
    TaskImpl(Functor functor, Parameter parameter){
    _functor = functor;
    _parameter = parameter;
    }

    void Run(){
    _functor(_parameter);
    }

    private:
    Functor _functor;
    Parameter _parameter;
    };

    template<class Callee, class Parameter1>
    class Functor1{
    typedef void (Callee::*MemFunc)(Parameter1 param);
    public:
    Functor1(): _callee(NULL), _memfunc(NULL){}

    Functor1(Callee* callee, MemFunc memfunc){
    _callee = callee;
    _memfunc = memfunc;
    }

    void operator()(Parameter1 param){
    if(_callee && _memfunc)
    (_callee->*_memfunc)(param);
    }
    private:
    Callee* _callee;
    MemFunc _memfunc;
    };


    Usage:

    class Bar
    {
    public:
    Bar(void) {}
    ~Bar(void){}
    void PrintString(std::string aString){
    cout << aString.c_str() << endl;
    }
    };

    int main(){
    Bar bar;
    Functor1<Bar, std::string> func(&bar, &Bar::printString);

    std::string aString = "Hello World";
    TaskImpl<Functor1<Bar, std::string>, std::string> task(func, aString);
    task.Run();
    }


    (next stop creating functors out of non-member functions...)
     
    Gordon Scott, Aug 17, 2003
    #2
    1. Advertising

  3. Gordon Scott wrote in
    news:MCS%a.19218$:

    > Thanks a bunch,
    >
    > using your help and these two articles
    >
    > http://www.tutok.sk/fastgl/callback.html
    > http://www.codeproject.com/cpp/CallbackDemo.asp
    >
    > I now have the following that allows me to make functors for calling
    > class member functions.
    > Are there any major problems with this implementation, or ways to
    > clean up?
    >


    Can't see any.

    [snip]

    > int main(){
    > Bar bar;
    > Functor1<Bar, std::string> func(&bar, &Bar::printString);
    >
    > std::string aString = "Hello World";
    > TaskImpl<Functor1<Bar, std::string>, std::string> task(func,
    > aString); task.Run();
    > }
    >
    >
    > (next stop creating functors out of non-member functions...)
    >
    >


    void nonmember( int i )
    {
    std::cout << "nonmember( " << i << " )" << std::endl;
    }

    int main()
    {
    TaskImpl< void (*)(int), int> task(nonmember, 2);
    task.Run();
    }

    Though if you do decide to create a functor for this, you may
    get some benefits from inlining, but I can't see it making
    much of a perfomance difference for a scheduled task.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
     
    Rob Williscroft, Aug 18, 2003
    #3
  4. Rob Williscroft

    Gordon Scott Guest

    Thanks for all the help.
    So far my C++ experience has mostly involved legacy C code with a couple of
    objects.
    This is the most fun I've had in a while.

    If you're interested, I followed Victor's idea and came up with

    template<class Functor, class Parameter>
    TaskImpl<Functor, Parameter> createTask(Functor f, Parameter p){
    return TaskImpl<Functor, Parameter>(f,p);
    }

    template <class Callee, class Parameter>
    Functor1<Callee, Parameter> createFunctor(Callee* callee,
    void(Callee::*MemFunc)(Parameter))
    {
    return Functor1<Callee, Parameter>(callee,MemFunc);
    }

    Seems to work like a champ.

    "Rob Williscroft" <> wrote in message
    news:Xns93DBC8B9381ukcoREMOVEfreenetrtw@195.129.110.200...
    > Gordon Scott wrote in
    > news:MCS%a.19218$:
    >
    > > Thanks a bunch,
    > >
    > > using your help and these two articles
    > >
    > > http://www.tutok.sk/fastgl/callback.html
    > > http://www.codeproject.com/cpp/CallbackDemo.asp
    > >
    > > I now have the following that allows me to make functors for calling
    > > class member functions.
    > > Are there any major problems with this implementation, or ways to
    > > clean up?
    > >

    >
    > Can't see any.
    >
    > [snip]
    >
    > > int main(){
    > > Bar bar;
    > > Functor1<Bar, std::string> func(&bar, &Bar::printString);
    > >
    > > std::string aString = "Hello World";
    > > TaskImpl<Functor1<Bar, std::string>, std::string> task(func,
    > > aString); task.Run();
    > > }
    > >
    > >
    > > (next stop creating functors out of non-member functions...)
    > >
    > >

    >
    > void nonmember( int i )
    > {
    > std::cout << "nonmember( " << i << " )" << std::endl;
    > }
    >
    > int main()
    > {
    > TaskImpl< void (*)(int), int> task(nonmember, 2);
    > task.Run();
    > }
    >
    > Though if you do decide to create a functor for this, you may
    > get some benefits from inlining, but I can't see it making
    > much of a perfomance difference for a scheduled task.
    >
    > Rob.
    > --
    > http://www.victim-prime.dsl.pipex.com/
     
    Gordon Scott, Aug 18, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul MG
    Replies:
    2
    Views:
    404
    Dhruv
    Jul 3, 2003
  2. red floyd
    Replies:
    0
    Views:
    339
    red floyd
    Nov 13, 2003
  3. nsgi_2004

    functors

    nsgi_2004, Aug 12, 2004, in forum: C++
    Replies:
    2
    Views:
    479
    Karl Heinz Buchegger
    Aug 12, 2004
  4. Satish
    Replies:
    1
    Views:
    804
    David Hilsee
    Sep 10, 2004
  5. Michael

    functors and stl find_if

    Michael, Feb 19, 2005, in forum: C++
    Replies:
    4
    Views:
    6,310
    SnaiL
    Feb 19, 2005
Loading...

Share This Page