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:

  1. È la mia comprensione delle regole corrette?

  2. Perché ::S sulla linea di fare nuovi trattati automaticamente S media struct, mentre nei mezzi ::S ultima linea le funzioni S nel namespace globale.

  3. Fa questo punto ad un'ambiguità nella documentazione, o è ancora un altro giorno per me di stare lontano da C ++ standard?

È stato utile?

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.

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