2010-08-12 5 views
1

je peux avoir un pointeur de fonction typedef dans une classe comme ceci:héritage pointeur de fonction typedef

template<typename T> 
class MyClass 
{ 

public: 

typedef T (*fptr)(T); 

    void doSomething(fptr my_fptr) { /*...*/ } 

}; 

et cela fonctionne très bien. mais si je hérite d'une telle classe, comme ci-dessous:

template<typename T> 
class MyClass 
{ 

public: 

typedef T (*fptr)(T); 

    virtual void doSomething(fptr my_fptr) = 0; 

}; 

template<typename T> 
class MyOtherClass: public MyClass<T> 
{ 

public: 

    void doSomething(fptr my_fptr) { /*...*/ } 

}; 

le compilateur se plaint que fptr est indéfini. existe-t-il un moyen d'hériter de typedefs de pointeur de fonction comme ceci? merci, james

+0

Quel compilateur utilisez-vous? La mienne ne s'en plaint pas. –

+0

@Seb Rose: Je suppose que vous utilisez VS ... c'est un problème connu avec ce compilateur. Le code selon la norme ne devrait pas compiler. –

+0

@dribeas - merci pour cela –

Répondre

1

Vous devriez pouvoir hériter des typedefs publiques comme ça.

Avez-vous essayé quelque chose comme ceci pour vous assurer que le compilateur sait qu'il est un type de parent:

void doSomething(typename MyClass<T>::fptr my_fptr) { /*...*/ } 
+0

cela l'a fait ... J'ai juste raté le nom de type au début. –

0

Je pense que le compilateur a besoin de plus d'informations en raison de la templating

essayer typename MyClass<T>::fptr

4

Le problème n'est pas lié à l'héritage, mais au fait qu'un modèle hérite de l'instanciation d'un autre modèle en passant son propre argument de modèle en paramètre. C'est-à-dire qu'il hérite d'un type dépendant (MyClass<T> dépend du type T).

La langue requiert que le modèle soit vérifié avant d'effectuer la substitution de type, et pendant ce premier passage, tous les noms non dépendants sont vérifiés. Lorsque le compilateur voit fptr il ne dépend pas du type T, il essaie donc de le localiser en dehors de votre modèle en tant que symbole de niveau d'espace de noms et échoue. Il n'est pas permis d'instancier MyBase avec le type (il n'y a pas de type pour la substitution) et en tant que tel l'ensemble MyBase est un inconnu et aucun symbole ne peut être recherché là-bas (sans substituer le type, le compilateur ne peut pas savoir s'il y a un spécialisation spécifique de MyBase).

La solution la plus simple est l'ajout d'une typedef locale:

typedef MyBase<T> base_type; 
typedef typename base_type::fptr fptr; 

ou bien qualifier l'appel:

void doSomething(typename MyClass<T>::fptr) ... 
0

Le problème est que la définition est dans une classe de base qui dépend d'un paramètre de modèle (connu en tant que dépendant de la classe de base); on ne sait pas jusqu'à ce que le template soit instancié ce qu'est réellement cette classe de base; différentes spécialisations pourraient avoir des membres différents. Donc, vous devez indiquer explicitement que c'est un type, défini dans la classe de base:

template<typename T> 
class MyOtherClass: public MyClass<T> 
{ 
    typedef typename MyClass<T>::fptr fptr; 
    // now fptr is available in this class template 
}; 

Pour accéder aux membres d'une classe de base dépendant, vous pouvez vous référer à eux comme soit MyClass<T>::member ou this->member.