1

I have a class that 'wraps' an AngelScript Method. Basically, you send it the Class, method return type, a pointer to the method, and a list of arguments.

So far, I am able to successfully make this Method object when I am 'binding' a class method that takes no parameters. However, if I try to add parameters, it breaks.

I am doing something like this:

template<typename C, typename R, R (C::*fn)(), typename... Arguments>
class Method {
public:
    Method()
    {
        const asSFuncPtr& func = asSMethodPtr<sizeof( void (C::*)() )>::Convert( AS_METHOD_AMBIGUITY_CAST( R (C::*)(Arguments... parameters)) (fn) );
        function = &func;
    };
    virtual ~Method(){};
    const asSFuncPtr* function;
};

struct S
{
    int f()
    {
        return 5;
    }

    int f(int a)
    {
        return a + 1;
    }
};

And then creating my Method object like so:

Method<S, int, &S::f> m = Method<S, int, &S::f>();

This works.

However, if I try to make a method object like this:

Method<S, int, &S::f, int> m2 = Method<S, int, &S::f, int>();

It breaks with this message:

template_tests.cpp: In instantiation of ‘Method<C, R, fn, Arguments>::Method() [with C = S; R = int; R (C::* fn)() = &S::f; Arguments = {int}]’:
template_tests.cpp:74:61:   required from here
template_tests.cpp:27:142: error: invalid static_cast from type ‘int (S::*)()’ to type ‘int (S::*)(int)’

Which makes sense, since I'm passing a pointer to a function that has no parameters.

Now, how do I change the Method class to accept method pointers to class methods that have varying number of parameters?

Do I do something like this:

template<typename C, typename R, R (C::*fn)(Arguments... parameters), typename... Arguments>
class Method {
...
}   

Because doing that causes all sorts of errors..

Basically, I guess I'm asking - how do I 'embed' variadic templates inside a template template? Is this possible?

Jarrett
  • 1,767
  • 25
  • 47
  • 3
    Do you really need the arguments and return types separately? What if `Method` was something like `template class Method`, and used like `Method`. – Vaughn Cato Apr 29 '13 at 02:31

1 Answers1

2

On the surface, it seems like your Method class doesn't really need the return type and the argument types, it just needs the the whole function type. In that case, Method could be defined like this:

template <typename C,typename Func,Func C::*fn>
struct Method {
public:
    Method()
    {
        const asSFuncPtr& func = 
           asSMethodPtr<sizeof( void (C::*)() )>::Convert( 
               AS_METHOD_AMBIGUITY_CAST(Func C::*) (fn) 
           );
        function = &func;
    };
    virtual ~Method(){};
    const asSFuncPtr* function;
};

and then used like this if the method takes no parameters:

Method<S, int(), &S::f> m;

or this if the method takes an int parameter:

Method<S, int(int), &S::f> m;
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132
  • Yes, and then some variadic template helper classes could be used to pull apart the return type and argument types – Ben Voigt Apr 29 '13 at 02:52
  • wow - that worked perfectly. Thanks so much @Vaughn! I definitely have a lot to learn with this c++ template stuff. – Jarrett Apr 29 '13 at 03:09