2011-11-26 8 views
6

Non capisco questo:Cosa significa "grammatica alternativa" [[compare oltre agli attributi?

(7.6.1) Due consecutivi sinistra gettoni parentesi quadra devono comparire solo quando l'introduzione di un fi catore attributo specifico. [Nota: se appaiono due parentesi quadre consecutive consecutive da in cui non è consentito specificare un attributo, il programma non è corretto anche se le parentesi corrispondono a una produzione di grammatica alternativa . -end nota] [Esempio: (leggermente modificato dalla fonte)

// ... 
void f() { 
int x = 42, y[5]; 
    // ... 
    y[[] { return 2; }()] = 2; // error even though attributes are not allowed 
          // in this context. 
} 

Cosa grammatica alternativo può essere utilizzato per [[? L'esempio sarebbe valido se gli attributi non esistessero (e cosa fa l'esempio)?

+4

Ho la sensazione che potrebbe finire per somigliare al fiasco ">>": tecnicamente richiesto per essere analizzato in un modo specifico, ma col tempo si insinuerà la clemenza e lo standard potrebbe allentare il vincolo. Detto questo, dato il numero elevato di situazioni in cui gli attributi possono essere usati, rende il lavoro dei compilatori molto più semplice per analizzare sempre '[[' come identificatore di attributo (che a sua volta rende la funzione più facile da usare). – GManNickG

+0

@GMan: E sembra che non ci sia altro modo che attraverso lambda per ottenere un [['' token al di fuori degli attributi. – Xeo

+0

@Xeo: Ho solo Ctrl + F'd attraverso la grammatica di C++ 0x e sembra essere vero. Non sono esperto di attributi, e non penso che sarebbe valido, ma ecco un metodo che non avrebbe bisogno di lambdas: 'struct {void operator [] (void *) {}} x; x [[[blah]] new int]; '. Non penso che tu possa applicare un attributo del genere, ma questa è l'idea generale. – GManNickG

risposta

2

L'esempio crea un lambda semplice, che viene chiamato direttamente e restituirà solo 2. Ciò otterrà il terzo elemento dall'array e lo assegnerà a 2. Potrebbe essere riscritto come segue:

int foo(){ return 2; } 

int y[5]; 

y[foo()] = 2; 

O anche

int y[5]; 

auto foo = []{ return 2; }; // create lambda 

y[foo()] = 2; // call lambda 

Ora, se non esistessero gli attributi, l'esempio potrebbe naturalmente essere ben formato, perché la sezione che ha citato wouldn esiste

+0

Oh! Ciò ha senso. Lascio questo aperto per un po 'nel caso ci siano altri casi. – Pubby

+3

@Pubby: La ragione per cui '[]' è stata selezionata come sequenza dell'induttore lambda era perché non esisteva alcun caso legittimo in cui '[' poteva essere usato senza un identificatore o qualche altra espressione di fronte ad esso. Quindi, senza lambdas, non c'è modo che "[[' potrebbe mai essere una sequenza legittima di token. –

+5

In realtà aggiungere una coppia di '()' dovrebbe essere sufficiente per risolvere il problema. 'y [([] {return 2;}())] = 2;' – kennytm