2011-11-26 10 views
6

No entiendo esto: aparecerán¿Qué 'gramática alternativa' hace [[aparece en además de los atributos?

(7.6.1) Dos fichas corchete izquierdo consecutivos sólo cuando la introducción de un fi cador de atributo-específica. [Nota: si aparecen dos corchetes izquierdos consecutivos donde no se permite un atributo específico, el programa está mal formado aunque los corchetes coincidan con una producción de gramática alternativa . -end nota] [Ejemplo: (ligeramente modificado a partir de fuente)

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

¿Qué gramática alternativo puede [[ ser utilizado para? ¿Sería el ejemplo válido si los atributos no existieran (y qué hace el ejemplo)?

+4

Tengo la sensación de que podría terminar como el fiasco '>>': técnicamente necesario para ser analizado de una manera específica, pero con el tiempo surgirá la indulgencia y el estándar puede relajar la restricción. Dicho esto, dada la gran cantidad de situaciones en las que se pueden usar los atributos, hace que el trabajo de los compiladores sea mucho más simple de analizar siempre '[[' como un especificador de atributos (que a su vez hace que la característica sea más fácil de poner en marcha). – GManNickG

+0

@GMan: Y parece que no hay otra manera que mediante lambdas de obtener un token '[[' fuera de los atributos. – Xeo

+0

@Xeo: Solo controlé Ctrl + F'd a través de la gramática de C++ 0x y eso parece ser cierto. No soy experto en atributos, y no creo que esto sea válido, pero aquí hay un método que no necesitaría lambdas: 'struct {void operator [] (void *) {}} x; x [[[blah]] nuevo int]; '. No creo que puedas aplicar un atributo como ese, pero esa es la idea general. – GManNickG

Respuesta

2

El ejemplo crea un lambda simple, que se llama directamente y que simplemente devolverá 2. Esto obtendrá el tercer elemento de la matriz y lo asignará a 2. Podría reescribirse de la siguiente manera:

int foo(){ return 2; } 

int y[5]; 

y[foo()] = 2; 

O incluso

int y[5]; 

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

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

Ahora, si no existieran los atributos, el ejemplo podría ser, por supuesto, bien formado, debido a que la sección se citó wouldn existo

+0

¡Oh! Eso tiene sentido. Dejaré esto abierto por un tiempo en caso de que haya otros casos. – Pubby

+3

@Pubby: El motivo '[]' se seleccionó como la secuencia del inductor lambda porque no había ningún caso legítimo donde '[' se pudiera usar sin un identificador o alguna otra expresión delante de él. Entonces, sin lambdas, no hay forma de que '[[' pueda ser una secuencia legítima de tokens. –

+5

En realidad, agregar un par de '()' debería ser suficiente para solucionarlo. 'y [([] {return 2;}())] = 2;' – kennytm

Cuestiones relacionadas