vendredi 11 septembre 2015

Compose variadic template argument by transforming them

I have a simple situation which probably require a complex way to be solved but I'm unsure of it.

Basically I have this object which encapsulated a member function:

template<class T, typename R, typename... ARGS>
class MemberFunction
{
private:
  using function_type = R (T::*)(ARGS...);

  function_type function;

public:
  MemberFunction(function_type function) : function(function) { }

  void call(T* object, ARGS&&... args)
  {
    (object->*function)(args...);
  }   
};

This can be used easily

MemberFunction<Foo, int, int, int> function(&Foo::add)
Foo foo;
int res = function.call(&foo, 10,20)

The problem is that I would like to call it by passing through a custom environment which uses a stack of values to operate this method, this translates to the following code:

int arg2 = stack.pop().as<int>();
int arg1 = stack.pop().as<int>();
Foo* object = stack.pop().as<Foo*>();
int ret = function.call(object, arg1, arg2);
stack.push(Value(int));

This is easy to do directly in code but I'd like to find a way to encapsulate this behavior directly into MemberFunction class by exposing a single void call(Stack& stack) method which does the work for me to obtain something like:

MemberFunction<Foo, int, int, int> function(&Foo::add);
Stack stack;
stack.push(Value(new Foo());
stack.push(10);
stack.push(20);
function.call(stack);
assert(stack.pop().as<int>() == Foo{}.add(10,20));

But since I'm new to variadic templates I don't know how could I do in efficiently and elegantly.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire