Domanda

Sarebbe bello se questo codice non sono validi. Ma è concettualmente solido, e GCC accetta anche se Comeau non lo fa:

template< typename > struct t;

template<> struct t< int > {} r; // Bad declarator! Don't pee on the carpet!

( Modifica le compilazioni di cui sopra, ma non sembra r da dichiarare in qualsiasi ambito , quindi è sostanzialmente ignorato.)

specializzazioni espliciti popolano una sorta di regione inferi tra i modelli e le classi. Il tipo dichiarato da una specializzazione esplicita è completo una volta che è definito. Dal punto di vista del compilatore, non è un modello. Se si trattasse di un modello con parametri, dichiarando un oggetto sarebbe impossibile. Considerare §14 / 3:

In un modello di dichiarazione, specializzazione esplicita, o di un'istanza esplicita l'init-dichiaratore-list nella dichiarazione deve contenere al massimo un dichiaratore. Quando si utilizza un tale dichiarazione per dichiarare un modello di classe, non è consentita alcuna dichiaratore.

Che cosa significa "è usato per dichiarare un modello di classe" media? Chiaramente un modello primario dichiara un modello di classe. E una specializzazione parziale non troppo, secondo §14.5.5 / 1 (numeri FDIS):

Una dichiarazione modello in cui il nome del modello di classe è un semplice-template-id è una specializzazione parziale del modello di classe di nome nella semplice-template-id.

Quando si tratta di specializzazioni esplicite, però, lo Standard parla in termini di una dichiarazione preceduta dalla template<> sequenza di token. E ' aspetto come un modello e nomi di un modello di nome, ma non sembra dichiarare un modello.

La cosa veramente strana è che §14 / 3 limita il numero di dichiaratori a "al massimo una." Una dichiarazione modello di funzione, specializzazione esplicita o di un'istanza deve avere esattamente un dichiaratore. Ogni dichiarazione relativa a un modello di classe deve avere esattamente pari a zero ... tranne specializzazione esplicita, che sembra cadere attraverso le fessure. Fedelmente, GCC rifiuta di consentire

template<> struct t< int > {} r, s; // Offer valid one per specialization.

Sono d'accordo con l'interpretazione di GCC, una sciocchezza come può essere. Purtroppo, può essere inibente sua capacità di rilevare e virgola mancanti. Ti prego, fa il numero di dichiaratori consentite essere esattamente pari a zero!

È stato utile?

Soluzione 2

specializzazione esplicita e istanziazione esplicita non dichiarano un modello. Essi dichiarano un template-id che si riferisce a una specializzazione, che è una classe.

Tuttavia, questo non convalida il mio esempio. Il problema è che tutto ha dichiarato dopo template o template<> fa parte l'istanza esplicita o di specializzazione, rispettivamente. Solo alcuni tipi di entità possono essere specializzati o istanziati, e nomi precedentemente non dichiarati non sono uno di loro.

Considerare questi esempi rendendo gratuito, ma l'uso legale di elaborati-type-specificatori (§7.1.5.3):

template< typename T > struct s;
template< typename T > s< int > *f() {}

template<> struct u *f< char >(); // struct u is declared
u *p = 0; // see, we can use its name now.
template<> struct s< int > *f< int >(); // s<int> declared but not specialized
template struct s< int > *f< long >(); // s<int> declared but not instantiated

Per quanto posso dire, lo Standard è confusa sulla specifica che ha dichiarato nome è quello specializzato. Il linguaggio non debolmente implica che ogni tale dichiarazione si applica ad un solo modello: §14.7.2 / 2

Se l'istanza esplicita è per una classe, una funzione o un membro modello di specializzazione ...

e §14.7.3 / 2

Una specializzazione esplicita deve essere dichiarato nello spazio dei nomi di cui il modello è un membro ...

L'unico modo per risolvere questo è di ignorare la dichiarazione del tipo se il dichiaratore specifica anche un legale di un'istanza / specializzazione.

Come arrivare al punto, gli esempi nella questione specifica illegali specializzazioni del dichiaratore e poi si aspettano il compilatore di fare marcia indietro e specializzati il ??tipo di posto. Date le liste esplicite di ciò specializzazioni e le dichiarazioni sono autorizzati a fare in §14.7.2 / 1 e §14.7.3 / 1, sembra più ragionevole lamentarsi template<> struct t< int > {} r; che r non è una funzione di modello, modello di funzione membro, dati statici membro di una classe template, ecc.

Altri suggerimenti

Diversi punti: in primo luogo, le specializzazioni esplicite non sono in un Nether regione tra modelli e classi; una specializzazione esplicita è un di classe, punto. L'unica relazione è ha con i modelli (ad eccezione del buffo nome) è che verrà utilizzato al posto di un modello di un'istanza se il modello è quello di essere istanziati dal tipo di specializzazione.

In secondo luogo, se c'è un problema con il paragrafo in §14 / 3 che si citare, è che esso include esemplificazione esplicito; un esplicito esemplificazione è una definizione di classe, e se

struct S {} s, *p;

è legale,

template<> struct T<int> {} s, *p;

dovrebbe essere troppo. (Vorrei argomentare contro permettendo sia, ma quel treno ha già lasciato la stazione, e dal momento che C permette la prima, siamo bloccati con esso.)

In caso contrario, l'affermazione nel §14 / 3 è un po 'irrilevante. Una funzione modello deve avere esattamente un dichiaratore, e un modello di classe esattamente zero; non c'è bisogno di cercare di inglobare tutti e due in un certo "al massimo una" burocratese. (Se fossi progettando la lingua da zero, io non avevo consentire a qualsiasi dichiaratore in una dichiarazione che definisce una classe o enum genere. Ma ancora una volta, è troppo tardi per questo.)

E sono d'accordo che si tratta di un fastidio:

template<> struct T<int> {};    //  Requires a ';'
template<> void f<int>() {}     //  ';' forbidden

(Almeno C ++ 11 permetterà una virgola dopo la definizione della funzione.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top