2011-11-03 15 views
6

Lo standard ISO 98/03 (sezione 14.3.1) sembra vietare l'utilizzo di un tipo con collegamento interno come parametro del modello. (Vedi esempio sotto). Lo standard C++ 11 no. G ++ - utilizzando il vecchio standard - lo sta permettendo. Sto fraintendendo lo standard 03, o è g ++ che lascia solo questa slide?Tipo interno come argomento modello

namespace 
{ 
    struct hidden { }; 
} 

template<typename T> 
struct S 
{ 
    T t; 
}; 

int main() 
{ 
    S<hidden> s; 
    return 0; 
} 
+0

Quale versione g ++? Potrebbe essere un'estensione –

risposta

7

siete sulla strada giusta che C++ 03 non consente utilizzando un tipo con collegamento interno come parametro di tipo di modello, mentre C++ 11 fa.

Mi sembra di ricordare, tuttavia, che le definizioni all'interno dello spazio dei nomi anonimo hanno ancora il collegamento esterno.


Yup, sezione 3.5 [basic.link] dice

Un nome avente namespace portata (3.3.5) ha il collegamento interno se è il nome di

  • un oggetto, di riferimento, funzione o modello di funzione che è esplicitamente dichiarato statico o,
  • un oggetto o riferimento che è esplicitamente dichiarato const e non dichiarato esplicitamente extern né precedentemente dichiarato di avere un collegamento esterno; oppure
  • un membro di dati di un'unione anonima.

Un nome avente portata namespace ha linkage esterno se è il nome di

  • un oggetto o di riferimento, se non ha il collegamento interno; oppure
  • una funzione, a meno che non abbia il collegamento interno; oppure
  • una classe denominata (clausola 9) o una classe senza nome definita in una dichiarazione typedef in cui la classe ha il nome typedef ai fini del collegamento (7.1.3); oppure
  • un'enumerazione con nome (7.2) o un'enumerazione senza nome definita in una dichiarazione typedef in cui l'enumerazione ha il nome typedef ai fini del collegamento (7.1.3); oppure
  • un enumeratore appartenente a un'enumerazione con collegamento esterno; oppure
  • un modello, a meno che non si tratti di un modello di funzione con collegamento interno (clausola 14); oppure
  • uno spazio dei nomi (7.3), a meno che non sia dichiarato all'interno di uno spazio dei nomi senza nome.

di avere una classe denominata in ambito namespace, ha linkage esterno.

e la nota nella parte inferiore della pagina 115 della norma ISO/IEC 14882: 2003 chiarisce:

Anche se le entità in un namespace anonimo potrebbe avere collegamento esterno, essi sono effettivamente qualificato da un nome unico per la loro traduzione unità e quindi non può mai essere visto da qualsiasi altra unità di traduzione.

Se si dispone di un'altra versione, provare a cercare nella sezione 7.3.1.1 [namespace.unnamed]

4

Questo non è un esempio valido della regola. La classe hidden nell'esempio ha collegamento esterno. (Ha un nome univoco generato dal compilatore in modo tale che nulla al di fuori l'unità di traduzione corrente in realtà può collegare con esso, ma è ancora esterno.)

La norma dà un esempio di un tipo di locale:

template <class T> class X { /* ... */ }; 
void f() 
{ 
    struct S { /* ... */ }; 

    X<S> x3; // error: local type used as template-argument 
    X<S*> x4; // error: pointer to local type used as template-argument 
} 
Problemi correlati