2010-03-30 7 views
2

Le code suivant0 pas valide FILE * lorsque fourni en argument de modèle

#include <stdio.h> 
template <typename T, T v> class Tem 
{ 
    T t; 
    Tem() 
    { 
     t = v; 
    } 
}; 

typedef Tem<FILE*,NULL> TemFile; 

lors de la compilation d'un fichier .mm (Objective C++) par Xcode sur MacOS X, jette l'erreur suivante:

Erreur

: impossible de convertir l'argument de modèle '0' en 'FICHIER *'.

Que se passe-t-il? Le code en question compilé bien sous MSVC. Depuis quand la constante 0 n'est-elle pas un pointeur valide pour quelque chose? Est-ce un artefact d'Objective C++ (par opposition à C++ vanille)?

+0

Pour ce que ça vaut, utilisez la liste d'initialisation pour initialiser les membres: 'Tem(): t (v) {}' – GManNickG

+0

Hmm, le code ressemble à "vanilla" C++. Je pensais que l'objectif C++ ressemblait à "[trucs ici] scary-tokens là-bas". Ou était-ce objectif-C oO –

+0

Ne peut pas croire que c'est une extension propriétaire de Microsoft. Les paramètres de modèle d'entier sont-ils également interdits? –

Répondre

1

Selon la norme, vous n'avez pas de chance. Il n'y a aucun moyen d'initialiser un argument pointeur à quoi que ce soit en plus de l'adresse d'un global. §14.3.2/1:

A template-argument for a non-type, non-template template-parameter shall be one of:

  • an integral constant-expression of integral or enumeration type; or
  • the name of a non-type template-parameter; or
  • the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or
  • a pointer to member expressed as described in 5.3.1 .

§14.3.2/5:

  • for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and the array-to-pointer conversion (4.2) are applied. [Note: In particular, neither the null pointer conversion (4.10) nor the derived-to-base conversion (4.10) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. ]

Cependant, Comeau accepte cette solution de contournement invalide:

typedef Tem<FILE*, (FILE *) NULL > TemFile; 

Ce code a une mince chance de conformité: je ne peux pas trouver où la norme dit spécifiquement qu'une expression par défaut est utilisée verbatim à la place d'un argument manquant, et je ne peux pas trouver un défaut connu correspondant. Quelqu'un at-il une référence?

#include <stdio.h> 
template <typename T, T *v = (T*) 0> class Tem 
{ 
    T t; 
    Tem() 
    { 
     t = v; 
    } 
}; 

typedef Tem<FILE> TemFile; 

Pour plus de portabilité, vous pourriez envisager de créer un FILE FILE_NULL; faux, passer &FILE_NULL et test pour pointer-égalité avec celle au lieu de zéro.

+0

Comeau l'accepte probablement parce que c'est C++ 0x valide. –

+0

@Johannes: Merci, j'ai raté le nouveau point de balle qu'ils ont mis dedans et Comeau l'a accepté malgré "éteindre" C++ 0x. – Potatoswatter

-1

Avez-vous essayé quelque chose comme ça?

typedef Tem<FILE*,((FILE*)NULL)> TemFile; 

Peut-être essaie-t-il de déterminer le type de valeur NULL.

+0

Cela produirait une erreur différente: une conversion à un type autre qu'une intégrale ou un type d'énumération ne peut pas apparaître dans une expression constante –

Questions connexes