Accedere ad alcuni tipi di classi base dipendenti
-
21-08-2019 - |
Domanda
Qualcuno sa il motivo per cui utilizzando-dichiarazioni non sembrano lavorare per l'importazione di nomi dei tipi di classi di base dipendente? Lavorano per variabili e funzioni, ma almeno in GCC 4.3, che sembrano essere ignorate per i tipi.
template <class T>
struct Base
{
typedef T value_type;
};
template <class T>
struct Derived : Base<T>
{
// Version 1: error on conforming compilers
value_type get();
// Version 2: OK, but unwieldy for repeated references
typename Base<T>::value_type get();
// Version 3: OK, but unwieldy for many types or deep inheritance
typedef typename Base<T>::value_type value_type;
value_type get();
// Version 4: why doesn't this work?
using typename Base<T>::value_type;
value_type get(); // GCC: `value_type' is not a type
};
Ho una classe di base con una serie di typedef allocator in stile che mi piacerebbe ereditare tutto diversi livelli di eredità. La soluzione migliore che ho trovato finora è la versione 3 di cui sopra, ma io sono curioso di sapere perchè versione 4 non sembra funzionare. GCC accetta la dichiarazione using, ma sembra ignorarlo.
Ho controllato standard c ++, C ++ Prog. Lang. 3a ed. [Stroustrup], e C ++ Templates [Vandevoorde, Josuttis], ma nessuno sembra per affrontare sia che si utilizzi-dichiarazioni può essere applicata a tipi di classe di base a carico.
Nel caso in cui aiuta a vedere un altro esempio, qui è la stessa domanda che si pone , ma in realtà non ha risposto, sulla mailing list GCC. Il richiedente indica che egli ha visto 'utilizzando typename' altrove, ma che GCC non sembra sostenerlo. Non ho un altro compilatore conforme a disposizione per testarlo.
Soluzione
Come Richard Corden fa notare, questo problema è stato affrontato nel C ++ standard Nucleo Lingua Defect Reports dopo lo standard 2003 è stato ratificato: Come la parole chiave typename / template interagire con l'utilizzo di-dichiarazioni?
Proposta di delibera (aprile 2003 rivisto ottobre 2003):
Aggiungere un nuovo paragrafo alla parte inferiore del 7.3.3 [namespace.udecl]:
Se una dichiarazione using utilizza il typename parola chiave e specifica un Nome dipendente (14.7.2 [temp.dep]), il nome introdotto dal dichiarazione using è trattata come un typedef-name (7.1.3 [dcl.typedef]).
Questo testo non sembra comparire nello standard Seconda edizione dal 15 ottobre, 2003.
GCC non ha ancora attuare questa risoluzione, come spiegato in bug 14258 :
------- Il commento # 3 Da Giovanni Bajo 2004-02-27 00:47 [risposta] ------- Il problema è che la nostra USING_DECL non lo fa registrare il "typename", vale a dire il fatto che si tratta di un tipo che è importata attraverso di essa. Ciò usata per funzionare grazie al nome del tipo implicito estensione, credo.
bug 21484 indica che 'utilizzando typename' funziona su Comeau e compilatori Intel. Perché MSVC tratta tutti i nomi come dipendenti, il costrutto è inutile (ma consentito) per questo compilatore.
fisso in GCC 4.7 da 13 dicembre il 2011!
Altri suggerimenti
Non è stato incluso uno specificatore di accesso (pubblico / protetto / privato) nel modello di base prima di dichiarare il typedef per Base :: value_type. Di conseguenza, il valore predefinito è privato e non è accessibile nelle classi derivate dalla base.