2010-04-27 6 views
3

J'ai du mal à compiler une classe qui a des pointeurs de fonction en tant que variables membres. Les pointeurs sont des fonctions qui prennent une instance d'une classe en argument.C++ Pointeur vers une fonction qui prend comme argument une instance d'une classe modèle

Comme

template<class T, int N> 
double (*f)(Vector<T,N> v); 

je reçois "erreur: les données membre 'f' ne peut pas être un modèle de membre" du compilateur gcc 4.2.

Modifier

Avant d'utiliser des modèles que je viens d'avoir

double (*f)(Vector v); 

Cela fonctionne également

double (*f)(Vector<double,2> v) 

Mais je voudrais avoir un pointeur de fonction pour une fonction qui prend un générique Vecteur comme argument ..

+1

Pouvez-vous publier la signature d'une fonction sur laquelle 'f' peut pointer? – rlbond

+2

Un peu plus de contexte serait utile pour suggérer ce que vous devriez faire. – GManNickG

Répondre

2

Utilisez un membre typedef:

template <typename T, int N> 
class Vector 
{ 
public: 

    /// type of function pointer 
    typedef double (*FuncPtr)(const Vector&); 

}; 

// concrete type 
typedef Vector<double,10> VecDouble10; 

// actual function 
double func(const VecDouble10>&); 

// usage 
VecDouble10::FuncPtr fp = func; 
+1

Je ne comprends pas le premier typedef, quel serait le nom d'alias pour le pointeur de fonction? – Nils

+0

Pourriez-vous expliquer un peu plus votre réponse, pourquoi devrait-il fonctionner avec typedef si ce n'est pas le cas? – Nils

+0

Il n'y a pas de magie - c'est juste un "template" pour un 'typedef' concret dans un template spécialisé. Vous pouvez explicitement utiliser un type comme 'double (* FP) (const Vector &)', 'typedef' le rend plus propre. –

0

Eh bien, le compilateur ne sait pas au moment de la compilation, combien de f allez-vous avoir (un pour chaque possible T et N?). Par conséquent, le compilateur ne peut pas calculer la quantité de mémoire dont les objets de votre classe ont besoin. C'est pourquoi de telles constructions sont interdites.

0

Vous ne pouvez pas avoir un pointeur de modèle pour fonctionner, cela n'a aucun sens. Mais ce que vous pouvez faire est

#include <vector> 

template <typename T> 
void foo(const std::vector<T>& v) { 
    // do something 
} 

void (*ptr_foo)(const std::vector<int>&) = &foo<int>; 

(ici la fonction pointeurs fonction basé sur un modèle, quel argument de modèle est explicitement défini sur int)

1

Ce n'est pas tout à fait valable C++, essentiellement ce que vous » À la recherche de paramètres template-template.

http://www.progdoc.de/papers/ttp/psi-ttp/psi-ttp.html explique tout sur les

En général, si vous vous entrez dans cette situation, vous voulez trouver un workaroumd, parce que votre code devient illisible très rapidement

0

Parce que votre code fait tout autant de sens comme:



struct X 
{ 
    template < typename T > 
    std::vector<T> vect; 
}; 

Vous essayez de faire un membre variables un modèle. Ce n'est pas une construction C++ valide et j'en doute sérieusement.

Comment faites-vous ce que vous voulez réellement? Je ne suis pas sûr puisque je ne sais pas ce que vous essayez réellement d'accomplir et pourquoi.

2

Si vous voulez avoir un « pointeur de modèle », vous pouvez essayer un objet de fonction. L'exemple ci-dessous ajoute 1.0 au modèle de fonction enveloppé.

struct AcceptsVector { 
    template<typename T, int N> 
    double operator()(Vector<T,N> v) const { return 1.0 + real_f(v); } 
}; 

AcceptsVector f; 

La différence à un pointeur de modèle « réel » est que vous ne pouvez pas re-siège « AcceptsVector » pour appeler un autre modèle, comme vous pouvez le faire avec des pointeurs de fonction normale. La liaison est codée en dur au moment de la compilation. Cependant, vous pouvez passer le f comme un pointeur de fonction, et appeler f avec n'importe quel Vector<T, N> comme un modèle.

Questions connexes