2010-07-18 22 views
10

Si consideri la seguente classe:senza indicazione di tipo di modello Parametri

class Foo 
{ 
    enum Flags {Bar, Baz, Bax}; 

    template<Flags, class = void> struct Internal; 

    template<class unused> struct Internal<Bar, unused> {/* ... */}; 
    template<class unused> struct Internal<Baz, unused> {/* ... */}; 
    template<class unused> struct Internal<Bax, unused> {/* ... */}; 
}; 

Lo schema di classe sopra compila e funziona come previsto quando testato su VC++ 2010 e Comeau C++. Tuttavia, quando Foo è realizzato in un modello di per sé, le interruzioni di sopra frammento sotto VC++ 2010.

Ad esempio, il seguente frammento:

template<class> class Foo 
{ 
    // Same contents as the original non-templated Foo. 
}; 

ottengono i seguenti error class:

C2754: 'Foo<<unnamed-symbol>>::Internal<Bar,unused>' : a partial specialization cannot have a dependent non-type template parameter 
C2754: 'Foo<<unnamed-symbol>>::Internal<Baz,unused>' : a partial specialization cannot have a dependent non-type template parameter 
C2754: 'Foo<<unnamed-symbol>>::Internal<Bax,unused>' : a partial specialization cannot have a dependent non-type template parameter 

  1. Qualcuno può spiegare cosa sta succedendo qui in inglese?
  2. Come posso risolvere questo problema (ad esempio, mantenere le specializzazioni pseudo-esplicite interne in un modello Foo) su VC++ 2010?
+1

Direi che i messaggi di errore sono falsi. FWIW, Comeau accetta il codice anche se 'Foo' è un modello. Ti suggerisco di provare in uno dei newsgroup di MS. I compilatori di MS erano soliti frequentare lì. – sbi

risposta

4

Come posso risolvere il problema (cioè, mantenere specializzazioni pseudo-esplicita interni in un Foo su modelli) su VC++ 2010?

È possibile effettuare il tipo di enumerazione non-dipendente dichiarando in una classe base non-modello (C++ 03 fatta classi annidate dipendenti in #108 ma che non include l'enumerazione, ma anche se, tale codice sarebbe ancora legale).

struct FooBase { 
    enum Flags {Bar, Baz, Bax}; 
}; 

template<class> class Foo : public FooBase { 
    template< ::FooBase::Flags, class = void > struct Internal; 
    // same other stuff ... 
}; 

Il collegamento "classe errore" fornisce già una descrizione dei casi previsti in cui l'errore deve essere aumentato. L'errore pensa che tutti i tipi dipendenti siano vietati, ma in realtà questo è quello che dice lo standard:

Il tipo di un parametro di modello corrispondente a un argomento di tipo non specifico non deve dipendere da un parametro della specializzazione .

Quindi, anche se il nome Flags sarebbe in qualche modo dipendente, che non rendono mal formata fintanto che non dipende da un parametro della specializzazione come nell'esempio della "classe di errore" collegamento.

+3

Abbastanza fastidioso che Microsoft non possa produrre un compilatore conforme considerando tutta la loro manodopera. Soprattutto quando si tiene conto del prezzo richiesto per le edizioni non libere. – rybz

+0

@litb: Non sono sicuro di seguirlo: in che modo i 'Flags' dipendono da un parametro della specializzazione? – HighCommander4

Problemi correlati