Derived functor with any return type and any parameters

I have a class that uses functors as units of work. It accepts a functor reference in its Run () method. For this class to work on any functor, all these functors must be derived from my base functor class, which looks like this:

class baseFunctor{

public:
    virtual void operator()()=0;
    virtual baseFunctor Clone()=0;
};

      

This works, however, obviously it restricts these functors to have an operator method that returns void and takes no parameters. I need to be able to accept a functor in my class that can take any parameters and return anything. Obviously he's capable, but I can't find a way to do it. I have considered using templates, multiple inheritance, but I keep being held back by the fact that the class that is supposed to run this functor must be able to take on any type, so it will take on the type of the base class and therefore will not know the actual type of the functor.

Any suggestions on what could be considered would be appreciated.

0


source to share


7 replies


How does the class that calls the functor know what parameters to supply and what to do with the return value, if any?



+2


source


If you are open to using the Boost library (www.boost.org), you may find Boot.Bind and Boost.Function of particular interest. I've used them in the past to achieve something very similar to what you are discussing.

If you're using Boost.Bind, you can curry on functors to account for the differences between the number of arguments the functor expects and the number of arguments the Run method expects (i.e. zero). The code that creates the functor will have to bind any arguments to specific values ​​and thus create a null argument functor that can be passed to Run ().



AT.

+1


source


So, if I'm reading this right, you have a "visitor template". You might look good.

Someone needs to know what type of functor is to give it arguments. Often with functors, arguments are assigned to fields of the derived class, and operator () will work on those fields. That is, a dumb method that calls a functor and doesn't know anything about it gets a closure (method plus arguments all in the same class) by someone more knowledgeable.

If you want generic functors to take multiple arguments to operator (), templating will be partially there, but you'll need one of them.

+1


source


I agree with Neal. Your main class needs to know what parameters should be passed and what return value to expect from those functors. Can you just jot a "functor" into the appropriate class that supports the function with the required arguments and return value?

class baseFunctor
{
};

class functor1x2: public baseFunctor
{
public:
    virtual void* execute(void*, void*);

}

class MainClass
{
public:
   void Execute(baseFunctor* ipFunctor)
   {
      functor1x2* lpFunctor1x2 = dynamic_cast<functor1x2*>(ipFunctor);
      if(lpFunctor1x2)
      {
         lpFunctor1x2->execute(NULL, NULL);
      }
   }
}

      

I'm not sure what could be done with this approach that couldn't be easier with a visitor template as Drew pointed out.

+1


source


Why do you want to return a functor? Are you also saving some kind of state? More details would be appreciated as it is not entirely clear what exactly you want to do.

If you plan on using inheritance, take a look at Covariant Return Types (and Virtual Constructor Idiom ).

Now, for the meat of the problem: the problem is really not the passing in the functor, but the functor app. You can take a look at boost::lambda

and boost::parameter

.

0


source


I think you want an ellipsis argument like varargs for C ++.

0


source


Perhaps you are interested in the std :: tr1 :: function?

0


source







All Articles