2013-04-29 4 views
1

J'ai une classe qui "enveloppe" une méthode AngelScript. Fondamentalement, vous lui envoyez la classe, le type de retour de méthode, un pointeur vers la méthode et une liste d'arguments.C++ modèles de modèles incorporés

Jusqu'à présent, je suis en mesure de réussir cet objet Method lorsque je suis "liaison" une méthode de classe qui ne prend aucun paramètre. Cependant, si j'essaie d'ajouter des paramètres, ça casse.

que je fais quelque chose comme ceci:

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

Et puis en créant mon objet Method comme ceci:

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

Cela fonctionne.

Cependant, si je tente de faire un objet de la méthode comme ceci:

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

Il rompt avec ce 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)’ 

Ce qui est logique, puisque je passe un pointeur vers un fonction qui n'a pas de paramètres.

Maintenant, comment est-ce que je change la classe Method pour accepter des pointeurs de méthode aux méthodes de classe qui ont le nombre variable de paramètres?

Est-ce que je fais quelque chose comme ceci:

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

Parce que faire cela provoque toutes sortes d'erreurs ..

En fait, je suppose que je demande - comment puis-je « Intégrer » modèles variadique intérieur un modèle de modèle? Est-ce possible?

+3

Avez-vous vraiment besoin des arguments et des types de retour séparément? Que faire si 'Method' était quelque chose comme' template classe Method, et utilisé comme 'Method '. –

Répondre

2

Sur la surface, il semble que votre classe Method n'a pas vraiment besoin du type de retour et des types d'argument, il a juste besoin de tout le type de fonction. Dans ce cas, Method pourrait être défini comme ceci:

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

puis utilisé comme celui-ci si la méthode ne prend aucun paramètre:

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

ou ceci si la méthode prend un paramètre int:

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

Oui, et puis quelques classes auxiliaires de modèle variadic pourraient être utilisées pour séparer le type de retour et les types d'argument –

+0

wow - cela a fonctionné parfaitement. Merci beaucoup @Vaughn! J'ai vraiment beaucoup à apprendre avec ce modèle de C++. – Jarrett