2010-09-07 7 views
3

reformulée QuestionModèle récursif?

Je trouve que ma question initiale était pas assez claire et les répliquants mal compris mon problème. Je vais donc essayer de clarifier:

Disons que j'ai deux classes:

struct C { void(*m_func)(C*); }; 
struct D { std::function<void(D*)> m_func; }; 

Maintenant, je veux faire une version générique des deux, donc je fais quelque chose comme ceci:

template<typename Func> 
struct G 
{ 
Func m_func; 
}; 

Mais maintenant, je ne sais pas comment instancier cette classe:

G<void(*)(G*)> c; //error 
G<std::function<void(G*)>> d; //error 

G<void(*)(G<void(*)(G<???>*)> *)> c; //??? 
G<std::function<void(G<std::function<void(G<???>*)>> *)>> d; //??? 

Quête originale ion:

Salut,

J'ai une classe de modèle qui peut prendre un pointeur de fonction ou un objet :: fonction std comme paramètre. Tout va bien jusqu'à ce que cette fonction utilise un pointeur de la classe de modèle dans sa signature:

#include <functional> 

template<typename Func> 
class C 
{ 
public: 
    C() {} 
    Func m_func; 
}; 

void foo() 
{ 
    C<void(*)(C*)> c; 
    C<std::function<int(C*)>> d; 
} 

erreurs pertinentes du compilateur:

error C2955: 'C' : use of class template requires template argument list 
error C3203: 'function' : unspecialized class template can't be used as a template argument for template parameter 'Func', expected a real type 
error C2955: 'std::tr1::function' : use of class template requires template argument list 

Comment il résoudre ce problème?

Répondre

2

Vous ne pouvez pas nommer le modèle récursif lui-même en dehors, mais vous pouvez le nommer à l'intérieur, comme la liste des paramètres est facultative dans une auto-référence.

Le problème devient alors de dire au modèle comment se transmettre à "quelque chose".

template< typename T > 
struct fptr_taking_type {  // this template is essentially a function 
    typedef void (*type)(T); // from types to types, the result being 
};        // the typedef 

template< typename T > 
struct stdfn_taking_type { 
    typedef function< void (*)(T) > type; 
}; 

template< template<typename> class F > 
struct G { 
    typename F< G * >::type m_func; // this declares the member variable 
}; 

... 

G<fptr_taking_type> q; 
+0

Merci. Je vais essayer ça. :) – user418680

2

C est un modèle de classe, pas une classe. Vous ne pouvez pas avoir un objet de type C ou un pointeur vers un C; vous pouvez seulement avoir des objets d'instanciations de C, comme C<int> ou C<float>.

2

Dans cette ligne:

 
    C<void(*)(C *)> c; 

Le C gras (italique ajouté) ne précise pas les paramètres du modèle. Vous devez spécifier quel type de C* prend ce pointeur de fonction, en spécifiant un type dans les parenthèses < >.

+0

Merci. Je comprends pourquoi le compilateur se plaint. Mais je ne sais pas comment résoudre ça. C *)> *)> ne fonctionne évidemment pas.:( – user418680

+0

Ce qu'ils disent est template classe C { public: C() {} Func m_func; }; void foo() { C *)> c; C *) >> d; } int main() { } – Chubsdad

+0

Oui, je comprends. Mais je veux que C * soit un pointeur de son propre type. c'est à dire. si le tout n'est pas un template, il ressemblerait à ceci: class C {void (* m_func) (C *); } – user418680

1

Est-ce que cela aide?

void foo1(){} 

template<typename Func> 
class C 
{ 
public: 
    C(Func f) : m_func(f) {} 
    Func m_func; 
    C<Func> *mp;     // it is a pointer, 
}; 

void foo() 
{ 
    C<void (*)(void)> c (foo); 
} 

int main(){ 
    C<void (*)(void)> c(foo); 
} 
0

Vous ne pouvez pas avoir de modèle récursif.

+0

Existe-t-il une sorte de récursivité que les modèles ne prennent pas en charge? – Potatoswatter