2010-11-28 7 views
6

L'exemple de code suivant est compilé sous gcc et fonctionne comme j'espère. Cela me permet d'instancier un objet avec une définition de fonction en tant que paramètre de modèle, mais ensuite la classe est capable d'utiliser les différents types de la fonction comme s'ils étaient passés individuellement en tant que paramètres de modèle de type.Conversion du paramètre de modèle non-type de pointeur de fonction en paramètres de modèle de type

template<class FuncSignature> class Obj; 

template<class Type1, class Type2> class Obj<Type1 (Type2)> 
{ 
public: 
    Type1 var1; 
    Type2 var2; 
}; 

int main(int argc, char **argv) 
{ 
    Obj<char (int)> A; 
    A.var1 = 'a'; 
    A.var2 = 3; 
} 

Même s'il semble fonctionner, je ne suis pas sûr de savoir ce que fait ce code. Pourquoi ce code fonctionne-t-il et est-il conforme à la norme C++?

+1

oui, c'est légal, en cas de doute, j'essaie http://www.comeaucomputing.com/tryitout/ pour vérifier la conformité. cela fonctionne en raison de la spécialisation de modèle partielle. – Anycorn

+0

Avec la méta-programmation, vous pouvez réellement extraire la plupart des informations sur un type de fonction (ici 'char (int)') en utilisant la bibliothèque Boost FunctionTypes: http://www.boost.org/doc/libs/1_45_0/libs/function_types/ doc/html/index.html Cela peut être un code, mais c'est une lecture intéressante :) –

Répondre

7

Pourquoi cela ne fonctionnerait-il pas? L'instanciation correspond à la spécialisation, qui extrait les types de composants (char et int) du type composé (une fonction, char(int)) en tant que Type1 et Type2. Par ailleurs, vous n'avez pas de paramètre de modèle non typé. Un type de fonction est un type. Si vous aviez un paramètre de modèle non-type, il serait alors ressembler à ceci:

template <char(int)> 
struct X {}; 

char foobar(int); 

int main() 
{ 
    X<foobar> x; 
} 

Ou bien basé sur un modèle:

template <class R, class A, R(A)> 
//       ^^^^ 
//      non-type parameter 
struct X {}; 

char foobar(int); 

int main() 
{ 
    X<char, int, foobar> x; 
//    ^^^^^^ 
// a specific function, not type 
} 
+2

Je sens une source de confusion ici: "Une fonction est un type". ce n'est pas vraiment vrai. Seulement si vous connaissez ces choses, vous pouvez déduire ce que signifie cette phrase. Pour réduire la source de confusion, mieux dire avec précision "Un type de fonction est un type". De même, un nombre entier n'est pas un type. Mais un type entier est. De la même manière, l'interrogateur s'est probablement confondu en disant «cela me permet d'instancier un objet avec une définition de fonction comme paramètre de modèle» - cette affirmation n'a aucun sens. –

+0

@Johannes: noté. – UncleBens

+0

Je vois que j'étais confus à bien des égards. Un être que je ne connaissais pas char (int) était un type connu comme un type de fonction. Je n'ai pas non plus réalisé qu'il existait une spécialisation de modèle basée sur ce type de fonction. Je n'ai jamais vu une spécialisation de modèle qui a une liste de modèles non vide. Y a-t-il d'autres cas que de se spécialiser dans un type de fonction où cela peut arriver? – user334066

3

Cette question est une fausse appellation car FuncSignature n'est pas un paramètre de modèle non-type.

Cependant, le code donné des œuvres en se spécialisant le (général) de type FuncSignature pour les types de fonction unaire (Type1 (Type2) est un type de fonction, types donné Type1 et Type2).

La première ligne définit un modèle général, le prochain groupe de lignes, il est spécialisé pour la forme de type Type1 (Type2), qui sont paramétrés sur deux types, d'où la spécialisation a une liste de paramètres du modèle non vide et le main instancie la modèle pour le type de béton char (int) (une fonction prenant un int et renvoyant un char).

0

Oui. Ce code est conforme à la norme :)

Dans le cas de:

Obj<char (int)> 

Type1 est char et Type2 est int. Pour cette raison, Obj::var1 est une variable membre de type char et Obj::var2 est une variable membre de type int.

Questions connexes