Nome ricerca Chiarimento
-
28-09-2019 - |
Domanda
$ 10.2 / 4- "[Nota: Sguardo in su un nome in un elaborato di tipo-specificatore (3.4.4) o base-specificatore (Clausola 10), per esempio, ignora tutto standardizzate dichiarazioni, durante la ricerca di un nome in un-nome-identificatore annidati (3.4.3) ignora funzione, variabile, e dichiarazioni Enumerator. "
Ho trovato questa dichiarazione di essere molto confusa in questa sezione nel descrivere su ricerca del nome.
void S(){}
struct S{
S(){cout << 1;}
void f(){}
static const int x = 0;
};
int main(){
struct S *p = new struct ::S; // here ::S refers to type
p->::S::f();
S::x; // base specifier, ignores the function declaration 'S'
::S(); // nested name specifier, ignores the struct declaration 'S'.
delete p;
}
Le mie domande:
-
È la mia comprensione delle regole corrette?
-
Perché
::S
sulla linea di fare nuovi trattati automaticamenteS
media struct, mentre nei mezzi::S
ultima linea le funzioniS
nel namespace globale. -
Fa questo punto ad un'ambiguità nella documentazione, o è ancora un altro giorno per me di stare lontano da C ++ standard?
Soluzione
Q1: Penso di sì
. Q2: La compatibilità con C. Quando si dichiara una struct
in C, il nome del tag è proprio questo, un nome di tag. Per essere in grado di utilizzare in modo autonomo, è necessario un typedef
. In C ++ non è necessario il typedef, che fa vivere più facile. Ma le regole C ++ sono state complicate dalla necessità di essere in grado di importare le intestazioni C già esistenti che "sovraccarico", il nome tag con un nome di funzione. L'esempio canonico che è la funzione stat()
Unix che utilizza un struct stat*
come argomento.
Q3: lettura standard è di solito abbastanza difficile ... avete bisogno di sapere già che non c'è posto modificando altrove quello che stai leggendo. Non è strano che la gente saper fare che sono avvocato lingua ...
Altri suggerimenti
Vi sbagliate circa il secondo commento. Nel S::x
, il S
è un nome in un nome specificatore nidificato. Ciò che la norma si riferisce a con "base-identificatore" è il seguente
namespace B { struct X { }; void X() }
struct A : B::X { }; // B::X is a base-specifier
Sei, inoltre, non corretto di questo:
::S();
// nome annidato specificatore, ignora la dichiarazione struct 'S'.`
Questo codice chiama la funzione non perché ::S
sarebbe un-nome-specificatore annidati (non è un nested-nome-identificatore!), Ma perché i nomi di funzione si nascondono nomi di classe o di enumerazione se sia la funzione e la classe / enumerazione sono dichiarati nello stesso ambito.
FWIW, il seguente codice sarebbe ugualmente valido per la linea 2 della vostra principale
p->S::f();
Quello che è importante è che preceedes S
un ::
, che fa ricerca di ignorare la funzione. Che si mette ::
prima S
non ha alcun effetto nel tuo caso.