2010-08-14 5 views
15

Existe-t-il des restrictions/problèmes utilisant un enum comme argument template (type) en C++?Utilisation d'enum comme argument de type de modèle dans C++

Exemple:

enum MyEnum 
{ 
    A, B, C, D, E 
}; 

template <typename _t> 
class MyTemplate 
{ 
public: 
    _t value; 

    void func(const _t& param) { /* .... */ } 
}; 

// .... 

MyTemplate<MyEnum> MyInstance; 

Mon problème réel en utilisant MSVC++ via VS 2008 (SP1) sur Win32/x86 sont plusieurs erreurs de compilation (erreurs = rapportées par le compilateur) en association avec des classes en utilisant les énumérations comme arguments de modèle. Comme mon projet est malheureusement devenu un peu complexe (vous pouvez considérer cela comme une erreur de conception: P), les classes de template qui provoquent ces erreurs sont dérivées, imbriquées et même spécialisées sur une classe avec un paramètre de template enum.

En essayant de construire, le compilateur signale de nombreuses erreurs erronées/inutiles telles que "C2059: erreur de syntaxe: 'public'" dans les lignes où il n'y a qu'un commentaire. Beaucoup d'entre eux je pourrais fixer en remplaçant dans les méthodes semblables à l'exemple le const _t & param par _t (c.-à-d. Copiant le paramètre), mais je ne pourrais pas non plus corriger toutes ces erreurs ". ** Je sais, l'exemple simple ci-dessus compile w/o erreurs.

En utilisant int au lieu de enum, mon projet compile les erreurs sans /.

Merci d'avance pour tout indice ou pourboire!


Modifier:

Après tout, je considère cela comme un sérieux bug du compilateur. Quand j'ai essayé de reproduire les erreurs avec du code simplifié, je les ai seulement dans 50% de tous les "builds", pas très déterministes:
E.g. essayé de compiler, et il a signalé ces erreurs. Reconstruire - pas de changement. Supprimé un commentaire, construire - pas de changement. Reconstruire - et ensuite: pas d'erreurs, compile bien.

J'ai déjà rencontré quelques bugs de compilation (2 ou 3 je suppose dans les 20k lignes de code), mais celui-ci me semble très étrange.
Toutes les suggestions comment savoir si est le compilateur?

+3

"En essayant de construire, le compilateur signale de nombreuses erreurs erronées/inutiles" Ces erreurs "inutiles" ont souvent une description très détaillée de ce qui s'est mal passé. Il suffit de lire la sortie du compilateur au lieu de "liste d'erreurs". – SigTerm

+0

Merci pour l'indice, mais je l'ai fait. Je le fais toujours ^^ Mais cela ne m'a pas aidé ... Erreurs: erreur C2059: erreur de syntaxe: erreur 'public' C2143: erreur de syntaxe: manquant '>' avant ';' erreur C2143: erreur de syntaxe: manquant ';' avant l'erreur fatale '}' C1004: fin de fichier inattendue trouvée (et ensuite d'autres erreurs, non liées à cette question) toutes ces erreurs n'apparaissent que lorsque vous utilisez l'enum et disparaissent en utilisant int – dyp

+0

Cela me semble parfaitement bien . C'est soit une erreur de compilateur ou votre erreur, et si vous allez deviner, le pari de 99,9% est que c'est vous. Mais il n'y a rien de mal avec les extraits que vous avez postés. Veuillez poster un petit échantillon complet en lui-même et les erreurs de compilation exactes qu'il crée. – Omnifarious

Répondre

4

Se référant à la question initiale:

are there any restrictions/problems using an enum as template (type) argument in C++?

je ne trouve pas - et je ne pense pas qu'il y ait. Cela pourrait s'avérer être une mauvaise idée parce que cette technique n'est pas souvent utilisée, donc il y a peut-être quelques (plus) bogues de compilateurs en rapport avec cela, comme l'a dit Potatoswatter.
Prenons l'exemple suivant:

enum MyEnum : int 
{ 
    A, B, C, D 
}; 

template <typename _t> class MyTemplate 
{ 
public: 
    void print() 
    { 
     cout << "not using any specialisation" << endl; 
    } 
}; 
    template <> class MyTemplate <MyEnum> 
    { 
    public: 
     void print() 
     { 
      cout << "MyEnum specialisation" << endl; 
     } 
    }; 
    template<> class MyTemplate <int> 
    { 
    public: 
     void print() 
     { 
      cout << "int specialisation" << endl; 
     } 
    }; 

template <typename _t> void print(_t param) 
{ 
    MyTemplate<_t> m; 
    m.print(); 
} 


int main() 
{ 
    print(A); 
    print(5); 

    return 0; 
} 

La sortie est:

MyEnum specialisation
int specialisation

Pour ces exemples simples, tout fonctionne bien et comme prévu et l'ENUM fonctionne parfaitement comme tout autre type comme modèle argument (= Je ne vois aucune raison pour les problèmes). À l'origine, j'ai présenté l'exemple dans la question pour montrer ce que je voulais dire avec cette question (enum comme argument de type template, montrer les utilisations possibles comme type d'argument member ou method et ainsi de suite). Pour fournir un peu de contexte, c'est-à-dire pourquoi j'ai posé cette question (imaginez que j'ai demandé "y at-il des problèmes avec int"), j'ai mentionné ces problèmes étranges compiler mon projet actuel. Je suis désolé de ne pas avoir pu extraire un extrait qui est complet en lui-même et qui reproduit les erreurs, le moins que je pouvais obtenir était 2k lignes de code séparées en 4 fichiers, où une "erreur de syntaxe: 'public'" et d'autres erreurs de syntaxe ont été soulevées lorsque j'ai compilé le projet, et elles sont apparues/ont disparu dans certaines circonstances, lors de la suppression d'un commentaire ou de la reconstruction (= suppression des fichiers intermédiaires). Malheureusement, la reconstruction n'aide pas avec le projet original, où j'ai dû remplacer une spécialisation d'un type enum à int.

Alors, merci à tous pour vos conseils et astuces. Le problème sous-jacent me semble être un bug du compilateur, ce qui rend la question un peu inutile, car la réponse semble être juste "non - il n'y a pas de restrictions utilisant un enum comme argument de type template". Désolé pour le dérangement.

0

MSVC gère étrangement les paramètres du modèle enum (value). Enums sont promus à int parfois incorrectement et les opérateurs ne sont pas définis correctement. Il semble qu'ils ne testent pas vraiment le moteur de template avec les types enum.

Prouver que c'est un bogue du compilateur est simple: mettez du code valide et observez s'il compile avec succès. Votre exemple est évidemment conforme, donc le problème (ou l'erreur, de toute façon) est le leur.

Modifier: regardant de plus près, vous dites que l'exemple ne pas reproduire le bug. Ni nous ni quelqu'un d'autre ne peut vous aider jusqu'à ce que vous produisiez un exemple qui le fait.

+0

On peut prouver qu'un compilateur a un bug que de deux manières: a) valident par rapport aux normes pertinentes b) lecture de la documentation et de vérifier si elle est un problème connu/défaut – Chubsdad

+0

L'OP n » t fournir une enum * value * comme paramètre de template - le type enum * * est le paramètre. –

7

Oui, il existe des restrictions. Par exemple, vous ne pouvez pas utiliser un énum anonyme comme argument de modèle selon C++ 03 14.3.1[temp.arg.type]/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

Ainsi, le code suivant est pas valable dans C: 03:

template <typename T> 
void f(T) {} 

enum {A}; 

int main() { 
    f(A); 
} 

Il est valide en C++ 11 cependant.

Questions connexes