2011-02-12 12 views
0

Il existe 2 classes de gabarit A et B ayant 2 membres privés a1, a2 et b1, b2.Pointeur vers le problème des méthodes et des modèles, C++

template <typename T> 
class A 
{ 
private: 
    T a1, a2; 

public: 
    T getA1() const {return a1;} 
    T getA2() const {return a2;} 

}; 


template <typename T> 
class B 
{ 
private: 
    T b1, b2; 

public: 
    T getB1() const {return b1;} 
    T getB2() const {return b2;} 

}; 

Dans la classe Test, il existe un besoin de 2 pointeurs pointant vers des getters.

class Test 
{ 
    private: 
    template <typename T> 
    static T (*getFirst)(); 

    template <typename T> 
    static T (*getSecond)(); 

} 


template <typename T> 
T (* Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error 

template <typename T> 
T (* Test::getSecond)() = &B<T>::getB2; //Pointer to getB2, error 

int main 
{ 
    A <double> a; 
    B <double> b; 

    double c = a.getFirst + b.getSecond; 
} 

T représente les types de données fondamentales ... Est-il possible de mettre en œuvre ce code sans spécialisation (à savoir des pointeurs vers des membres du modèle de classe) ou les « pointeurs » devraient être spécialisés? Merci pour tous les exemples ...

+0

J'ai essayé de composer une réponse, mais j'ai échoué pour une raison: je ne comprends pas ce que vous avez l'intention de faire avec votre test de classe. Vous en fournissez une définition qui comporte des erreurs, mais vous ne l'utilisez nulle part. La façon de corriger ces erreurs dépend en grande partie de la façon dont vous prévoyez de l'utiliser. Certaines des réponses ci-dessous peuvent vous être utiles, mais pour obtenir la bonne réponse, vous devez fournir un exemple d'utilisation de Test. –

Répondre

0

Vous faites des choses illégales. Voir cela,

template <typename T> 
static T (*getFirst)(); 

Ici vous essayez de définir le pointeur de fonction modèle qui est illégal en C++.

La norme C++ dit dans 14/1 $,

Un modèle définit une famille de cours ou fonctions.

S'il vous plaît noter qu'il ne pas dire « un modèle définit une famille de cours, fonctionsou des pointeurs fonction ». Donc, ce que vous essayez de faire est de définir "une famille de pointeurs de fonction" en utilisant le modèle, ce qui n'est pas autorisé.


Si vous voulez fonctionner pointeur que vous pouvez faire quelque chose comme ça,

template <class T> 
struct A 
{ 
    static T (*FunctionPointer)(); //function pointer 
}; 

struct B 
{ 
    template <class T> 
    static T Function(); //static function, not function pointer 
}; 

int (*A<double>::FunctionPointer)() = &B::Function<double>; 

Pourtant, une meilleure alternative est: utiliser function object. :-)

+0

Ok, merci ... Comment va regarder le code lorsque la fonction ne sera pas statique? Puis-je vous demander aussi un court exemple en utilisant des objets de fonction dans ce cas? – CrocodileDundee

0

Bref, ce n'est pas possible. D'abord, vous ne pouvez pas déclarer un pointeur sur la fonction du modèle, mais seulement sur une fonction concrète. Deuxièmement, vous avez essayé de déclarer le pointeur sur la fonction libre, mais A::getA1 est une fonction membre avec l'argument implicite this, donc la sémantique ne correspond pas.

Vous pouvez faire quelque chose comme ceci:

template <typename T> 
struct A 
{ 
    static T get() { return T() }; 
}; 

template <typename T> 
struct Holder 
{ 
    typedef T(A<T>::*F_ptr)(); 
    static F_ptr f_ptr; 
}; 


template <typename T> 
typename Holder<T>::F_ptr Holder<T>::f_ptr = &A<T>::get; 

pour garder le pointeur à la fonction de modèle en tant que membre de la classe de modèle

0

La ligne:

template <typename T> 
T (*Test::getFirst)() = &A<T>::getA1; //Pointer to getA1, error 

a deux problèmes: l'un est que &A<T>::getA1 est de type T (A::*)()const mais getFirst est de type T (*)(). Ceux-ci ne sont pas compatibles car le premier est un pointeur vers une fonction membre, tandis que le dernier ne l'est pas.

Le deuxième problème avec la ligne est que les objets créés ne diffèrent que par leur type de retour. Tout comme vous ne pouvez pas déclarer manuellement à la fois les codes double (A::*getFirst)()const et char (A::*getFirst)()const, vous ne pouvez pas non plus créer un modèle qui les déclare automatiquement tous les deux.

La ligne:

double c = a.getFirst + b.getSecond;

a son propre ensemble de problèmes qui peuvent ou ne peuvent pas porter la question à la main.

Désolé pour cette "non-réponse". Peut-être que si vous parliez davantage de ce que vous essayez d'accomplir, plutôt que de la façon dont vous essayez de l'accomplir, nous serons en mesure d'aider.

0

Votre code semble assez confus, donc je ne suis pas sûr d'avoir vraiment compris ce que vous demandez ... voici une adaptation de votre exemple qui compile.

// This is one template class A with two getters 
template <typename T> 
class A 
{ 
private: 
    T a1, a2; 

public: 
    T getA1() const {return a1;} 
    T getA2() const {return a2;} 
}; 

// This is another unrelated template class, with two other getters 
template <typename T> 
class B 
{ 
private: 
    T b1, b2; 

public: 
    T getB1() const {return b1;} 
    T getB2() const {return b2;} 
}; 

// These are declarations of generic "getFirst" and "getSecond" 
template<typename T1, typename T2> 
T1 getFirst(const T2& t); 

template<class T1, class T2> 
T1 getSecond(const T2& t); 

// Here I'm specializing getFirst/getSecond for the A template 
template<class X> 
double getFirst(const A<X>& a) { return a.getA1(); } 

template<class X> 
double getSecond(const A<X>& a) { return a.getA2(); } 

// Here I'm doing the same for the B template 
template<class X> 
double getFirst(const B<X>& b) { return b.getB1(); } 

template<class X> 
double getSecond(const B<X>& b) { return b.getB2(); } 

// Now I can use getFirst/getSecond with either A or B 
int main(int argc, const char *argv[]) 
{ 
    A<double> a; 
    B<double> b; 
    double c = getFirst(a) + getSecond(b); 
    return 0; 
} 
+0

Une solution intéressante, merci. – CrocodileDundee

Questions connexes