web-dev-qa-db-fra.com

C ++, pointeur de fonction vers le pointeur de fonction modèle

J'ai un pointeur sur la méthode statique courante

class MyClass
{
  private:
    static double ( *pfunction ) ( const Object *, const Object *);
    ...
};

pointant vers la méthode statique

 class SomeClass
 {
  public:
    static double getA ( const Object *o1, const Object *o2);
    ...
 };

Initialisation:

double ( *MyClass::pfunction ) ( const Object *o1, const Object *o2 )  = &SomeClass::getA;

Je voudrais convertir ce pointeur en pointeur de fonction de modèle statique:

template <class T>
static T ( *pfunction ) ( const Object <T> *, const Object <T> *); //Compile error

où:

 class SomeClass
 {
  public:
    template <class T>
    static double getA ( const Object <T> *o1, const Object <T> *o2);
    ...
 };

Mais il y a l'erreur de compilation suivante:

error: template declaration of : T (* pfunction )(const Object <T> *o1, const Object <T> *o2)

Merci de votre aide...

23
Ian

Dans le second cas, getA n'est plus une fonction mais une fonction template, et vous ne pouvez pas avoir de pointeur sur le modèle de fonction.

Ce que vous pouvez faire, c'est que pfunction pointe vers une notamment getA instance (c'est-à-dire: pour T = int):

class MyClass
{
    static double (*pfunction)(const Object<int> *, const Object<int> *);
};

double (*MyClass::pfunction)(const Object<int> *o1, const Object<int> *o2)  = &SomeClass::getA<int>;

Mais je ne pense pas qu'il existe un moyen de faire pointer pfunction sur tout instance possible de getA.

18
icecrime

le modèle est un modèle :) ce n'est pas un type concret et ne peut pas être utilisé comme membre. par exemple. vous ne pouvez pas définir la classe suivante:

class A
{
    template <class T> std::vector<T> member;
}

car template <class T> std::vector<T> member; est quelque chose qui peut être spécialisé dans de nombreux types différents. vous pouvez faire quelque chose comme ça:

template <class T>
struct A
{
 static T (*pfunction)();
};

struct B
{
 template <class T>
 static T getT();
};

int (*A<int>::pfunction)() = &B::getT<int>;

ici A<int> est un modèle spécialisé et a donc un membre spécialisé

12
Andriy Tylychko
template <class T>
static T ( *pfunction ) ( const Object <T> *, const Object <T> *);

Le modèle de pointeur de fonction est illégal en C++. Que ce soit à l'intérieur d'une classe ou simplement à l'extérieur d'une classe. Vous ne pouvez pas écrire ceci (même pas en dehors d'une classe):

template <class X>
void (*PtrToFunction) (X);

Voir cet exemple: http://www.ideone.com/smh7

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

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

Veuillez noter qu'il ne dit PAS "Un modèle définit une famille de classes, fonctions ou fonction pointeurs ". Donc, ce que vous essayez de faire, c'est de définir "une famille de pointeurs de fonction" à l'aide d'un modèle, ce qui n'est pas autorisé.

Les Functors génériques de la bibliothèque Loki seraient une solution élégante au type de problème que vous rencontrez. :-)

8
Nawaz

Une chose que vous pouvez faire est d'avoir une copie de la fonction membre du modèle dans le fichier cpp et de pointer vers cela, c'est-à-dire.

template <+typename ElementType>
int PQueueHeap<ElementType>::compareFunction(ElementType First,ElementType Second)
{   
    if (First>Second) return 1; else if (First==Second) return 0; else return -1;
}

// you cannot point to above 

mais vous pouvez indiquer

template <+typename ElementType>

int compareFunction(ElementType First,ElementType Second)
{

if (First>Second) return 1; else if (First==Second) return 0; else return -1;
} // No error and it works! 
2
Adel