vedere il seguente codice diUn comportamento strano di dichiarazione using
struct A { using type = int; };
struct B : private A {};
struct C : B { using base_type = A; };
Tutti gcc 6.1, clang 3.8, e msvc Aggiornamento 2015 3 rifiutano di compilare questo, come A
non è un nome accessibili all'interno C
dal A
è una base privata di B
. Sembra che gcc pensi che A
in using base_type = A
si riferisca al costruttore predefinito di A
. msvc e clang non sembrano.
Forse l'errore di compilazione è dovuto alla iniezione di nomi innescato da eredità (perché la modifica using base_type = A
in using base_type = ::A
fanno tutti i compilatori funzionano bene), ma voglio sapere se questo errore strano è ciò che dice lo standard.
Più concretamente,
- Come ho capito, non come
A::type
,A
è solo un nome di classe (anche se interpreta male gcc come un nome di funzione) che viene introdotto aC
non all'internoA
néB
. Perché questo nome è considerato privato perB
? - Questo errore di compilazione può essere considerato un bug o è un caso limite delle specifiche dello standard?
Suppongo che ciò sia dovuto al modo in cui il nome cerca "A' dentro" C ".Per prima cosa controlla se è stato dichiarato qualcosa con un nome 'A' nell'ambito di' C' prima di 'using'. Dal momento che non ne trova uno, lo sta controllando nell'ambito di 'B' dato che è la classe Base. E nel caso in cui non trovi l'estensione 'A' in' B', si troverà nello 'spazio dei nomi globale'. Ma in qualche modo "l'ereditarietà privata" di "A" di "B" viene fermata alla seconda ricerca all'interno dello scope di "B". Dal momento che funziona con il nome 'fully qualified', questo mi fa pensare che il vero problema debba essere sulla stessa linea. – Arunmu
http://eel.is/c++draft/class.access.spec#5 sembra rilevante –
@PiotrSkotnicki Grazie, risponde direttamente alla domanda. Ma puoi darmi il razionale dietro questa regola? –