2013-04-29 2 views
1

У меня есть класс, который «обертывает» метод AngelScript. В принципе, вы отправляете ему класс, метод возвращаемого типа, указатель на метод и список аргументов.C++ встроенные шаблоны шаблонов

До сих пор я мог успешно сделать этот объект Method, когда я привязываю метод класса, который не принимает никаких параметров. Однако, если я пытаюсь добавить параметры, он ломается.

Я делаю что-то вроде этого:

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; 
    } 
}; 

А затем создать свой Method объект следующим образом:

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

Это работает.

Однако, если я пытаюсь создать объект метод как это:

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

Он порывает с этим сообщением:

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)’ 

Который имеет смысл, так как я передаю указатель на функция, не имеющая параметров.

Теперь, как мне изменить класс Method, чтобы принять указатели метода методам класса, которые имеют различное количество параметров?

ли я сделать что-то вроде этого:

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

Потому что делать, что вызывает все виды ошибок ..

В принципе, я думаю, я спрашиваю - как я вставлять 'VARIADIC шаблоны внутри шаблон шаблона? Это возможно?

+3

Вам действительно нужны аргументы и типы возврата отдельно? Что, если 'Method' был чем-то вроде' template class Method' и использовался как 'Method '. –

ответ

2

На первый взгляд кажется, что вашему классу Method действительно не нужен тип возвращаемого значения и типы аргументов, ему просто нужен весь тип функции. В этом случае Method может быть определен следующим образом:

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; 
}; 

и затем использует, как это, если метод не принимает никаких параметров:

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

или это, если метод принимает параметр INT:

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

Да, а затем некоторые вариабельные классы вспомогательных шаблонов могут использоваться для разворота типа возвращаемого типа и типов аргументов –

+0

wow - это отлично работало. Большое спасибо @ Vaughn! Мне определенно нужно многому научиться с этим материалом шаблона C++. – Jarrett