2010-08-14 16 views
15

esistono restrizioni/problemi che utilizzano un enum come argomento template (type) in C++?Utilizzare enum come argomento del tipo di modello in C++

Esempio:

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

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

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

// .... 

MyTemplate<MyEnum> MyInstance; 

Il mio problema reale utilizzando MSVC++ tramite VS 2008 (SP1) in Win32/x86 sono diversi errori di compilazione (= errori segnalati dal compilatore) in associazione con le classi utilizzando le enumerazioni come argomenti del modello. Poiché purtroppo il mio progetto è diventato un po 'complesso (si può considerare che come errore di progettazione: P), le classi template che generano questi errori sono derivate, nidificate e persino specializzate su una classe con parametro del template enum.

Cercando di compilare, il compilatore riporta molti errori errati/inutili come "C2059: errore di sintassi: 'pubblico'" nelle righe dove c'è solo un commento. Molti di quelli che potevo risolvere sostituendo in metodi simili a quello nell'esempio il parametro const _t & di _t (cioè copiando il parametro), ma nessuno dei due era in grado di correggere tutti questi errori né ho un indizio sul perché questo "aiuta ". ** Lo so, il semplice esempio sopra compila senza errori.

Utilizzando int al posto di enum, il mio progetto viene compilato senza errori.

Grazie in anticipo per qualsiasi suggerimento o suggerimento!


Edit:

Dopo tutto, ho seriamente considerare questo come un bug del compilatore. Quando ho provato a riprodurre gli errori con codice semplificato, li ho ottenuti solo nel 50% di tutte le "build", non molto deterministiche:
Es. ha provato a compilare e ha segnalato questi errori. Ricostruisci - nessun cambiamento. Cancellato un commento, compilato - nessun cambiamento. Ricostruisci - e poi: nessun errore, compila bene.

Ho già incontrato alcuni bug del compilatore (2 o 3 credo entro 20k righe di codice), ma questo mi sembra molto strano.
Qualche suggerimento su come capire se lo è il del compilatore?

+3

"Cercando di compilare, il compilatore riporta molti errori errati/inutili" Questi errori "inutili" spesso hanno una descrizione molto dettagliata di cosa/e dove è andato storto. Basta leggere l'output del compilatore invece di "error list". – SigTerm

+0

Grazie per il suggerimento, ma l'ho fatto. Lo faccio sempre ^^ Ma non mi ha aiutato ... Errori: errore C2059: errore di sintassi: errore "pubblico" C2143: errore di sintassi: mancante '>' prima di ';' errore C2143: errore di sintassi: mancante ';' prima dell'errore fatale C1004 di "}": trovato inaspettatamente alla fine del file (e quindi alcuni altri errori, non correlati a questa domanda) tutti questi appaiono solo quando si utilizza l'enum e si annulla quando si utilizza int – dyp

+0

Questo mi sembra perfettamente a posto . Questo è un errore del compilatore o un tuo errore, e se hai intenzione di indovinare, la scommessa del 99,9% è che sei tu. Ma non c'è niente di sbagliato con i frammenti che hai postato. Si prega di inviare un piccolo esempio completo in sé e gli errori esatti del compilatore che crea. – Omnifarious

risposta

4

riferimento alla domanda iniziale:

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

non ho trovato alcuna - e non credo ce ne sono. Potrebbe rivelarsi una cattiva idea perché questa tecnica non viene utilizzata così spesso, quindi potrebbero esserci alcuni (più) bug del compilatore relativi a questo, proprio come ha detto Potatoswatter.
consideri il seguente esempio:

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; 
} 

L'output è:

MyEnum specialisation
int specialisation

Per questi semplici esempi, tutto funziona bene e come previsto e l'enumerazione funziona perfettamente come qualsiasi altro tipo come tipo di modello argomento (= Non vedo alcun motivo per problemi).

In origine, ho introdotto l'esempio nella domanda per mostrare cosa intendevo per quella domanda (enum come argomento del tipo di modello, mostra possibili utilizzi come tipo di argomento membro o metodo e così via). Per fornire un po 'di background, ad esempio perché ho posto questa domanda (immagino di aver chiesto "ci sono problemi con int"), ho menzionato questi strani problemi che compongono il mio progetto attuale.
Mi dispiace non aver potuto estrarre un frammento di esso che è completo in sé e riprodurre gli errori, il minimo che ho potuto ottenere sono stati 2k righe di codice suddivise in 4 file, dove un "errore di sintassi: 'pubblico'" e alcuni errori di sintassi sono stati sollevati durante la compilazione del progetto e sono comparsi/scomparsi in determinate circostanze, quando si elimina un commento o si ricostruisce (= eliminazione dei file intermedi). Sfortunatamente, la ricostruzione non aiuta il progetto originale, dove ho dovuto sostituire una specializzazione da un tipo enum a int.

Quindi, grazie a tutti per i vostri consigli e suggerimenti. Il problema di fondo mi sembra un bug del compilatore, ciò che rende la domanda un po 'inutile, poiché la risposta sembra essere solo "no - non ci sono restrizioni usando un enum come argomento del tipo di modello". Ci dispiace per l'inconvenienza.

0

MSVC gestisce i parametri del modello enum (valore) in modo strano. Le enumerazioni vengono promosse a int in modo errato a volte e gli operatori non sono definiti correttamente. Sembra che non testino realmente il motore di template con i tipi enum.

Provare che si tratta di un errore del compilatore è semplice: inserire codice valido e osservare se si compila correttamente. Il tuo esempio è ovviamente conforme, quindi il problema (o l'errore, comunque) è il loro.

Edit: un esame più attento si dice che l'esempio non non riprodurre il bug. Né noi né nessun altro possiamo aiutarti finché non produci un esempio.

+0

Si può dimostrare che un compilatore ha un bug solo in due modi: a) convalidare con gli standard pertinenti b) Leggere la documentazione e verificare se si tratta di un problema noto/difetto – Chubsdad

+0

L'OP non è • Fornendo un valore enum * come parametro del template - il tipo enum * è il parametro. –

7

Sì, ci sono restrizioni. Ad esempio, non è possibile utilizzare un enum anonimo come un argomento in base al modello 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.

Così il seguente codice non è valido per C++ 03:

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

enum {A}; 

int main() { 
    f(A); 
} 

E 'valido in C++ 11 però.

Problemi correlati