2012-07-03 15 views
34

¿C++ 11 permite declarar miembros de datos no estáticos como 'auto' si se inicializan en la declaración? Por ejemplo:C++ 11 - declaración de miembros de datos no estáticos como 'auto'

struct S 
{ 
    auto x = 5; // in place of 'int x = 5;', which is definitely allowed 
}; 

GCC 4.7 rechaza el código anterior, mientras se acepta int x = 5;.

Suponiendo que esto no es un error del compilador, sino que el estándar realmente no lo permite, ¿por qué no? Sería tan útil como declarar las variables locales auto.

+4

Se permite declarar un miembro de datos estáticos de esta manera, pero no un miembro de datos no estático (consulte la lista de usos autorizados de 'auto' en C++ 11 §7.1.6.4). Fuera de mi cabeza, no puedo pensar en una buena razón por la que está prohibido, aunque definitivamente consideraría que es un abuso de 'auto'. –

+0

@JamesMcNellis: ¿Por qué consideraría esto un abuso de 'auto'? ¿Cuál es la diferencia entre tener una variable con un nombre de tipo largo/complicado (para que sea deseable usar 'auto' en lugar de escribir su tipo) en el alcance de la clase frente a tener uno en el ámbito local? – HighCommander4

+4

En el alcance del bloque, sé cómo se está _utilizando_ la variable. En ámbito de clase o ámbito de espacio de nombres, no necesariamente sé cómo se usa la variable. Considere, por ejemplo, el más general 'auto x = f (a, b, c); ': tendría que buscar todas las funciones' f() 'y realizar una resolución de sobrecarga en mi cabeza para descubrir el tipo de 'x'. Al menos en el ámbito local, puedo ver qué se está haciendo con 'x' y tratar de deducir cuál es su tipo. 'auto' es increíblemente útil, pero no debe usarse _everywhere_. –

Respuesta

51

La regla para prohibir miembros no estáticos está en 7.1.6.4 cláusula 4:

El auto tipo especificador también se puede utilizar en la declaración de una variable en la condición de una declaración de selección (6.4) o una instrucción de iteración (6.5), en el type-specifier-seq en el new-type-id o type-id de una new-expression (5.3.4), en una declaración for-range, y en declarar un miembro de datos estáticos con un llavero o igual inicializador que aparece dentro de la especificación miembro de una definición de clase (9.4.2).

He encontrado la razón de que sea estática here que refleja cómo James McNellis explica en el comentario.

Un organismo nacional no le gusta lo que permite la auto-tipo especificador de no estática. Desde un e-mail a los autores:

template< class T > 
    struct MyType : T { 
     auto data = func(); 
     static const size_t erm = sizeof(data); 
    }; 

Con el fin de determinar la distribución de X, ahora tenemos búsqueda de nombre de 2 fases y ADL. Tenga en cuenta que func podría ser un tipo o una función; se puede encontrar en T, el espacio de nombres de MyType, el espacio de nombres asociado de T cuando se crea una instancia, el espacio de nombre global, un espacio de nombre anónimo o cualquier espacio de nombres sujeto a una directiva using. Con cuidado, probablemente podríamos lanzar alguna búsqueda de concept_map para tener suerte. Dependiendo del orden de inclusión del encabezado, podría obtener resultados diferentes para ADL y romper la regla de una sola definición, que no es necesario para el diagnóstico de .

Debido a esta controversia, los autores ya no proponen que se permita el auto para los miembros de datos no estáticos.

Por lo tanto, básicamente dependiendo del orden de inclusión del encabezado, el tipo de data podría ser muy diferente. Por supuesto, auto x = 5; no necesitaría depender de la búsqueda de nombre de dos fases o ADL, sin embargo, supongo que lo hicieron una regla "general" porque de lo contrario, tendrían que hacer reglas individuales para cada caso de uso que lo haría hacer las cosas muy complicadas

En el mismo documento, el autor propone eliminar esta restricción, sin embargo, parece que esta propuesta ha sido rechazada probablemente debido a la lógica anterior y también para que el comportamiento esperado sea el mismo sin importar el inicializador.

+5

¡Gracias por excavar eso, esa es una razón de ser interesante! – HighCommander4

+2

N.B. la propuesta original para permitirlo era [N2426] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2426.htm) –

+1

@JonathanWakely Realmente no hay esperanza de ver ese tema resucitado decir para C++ 20? Hay varios lugares en mi código que serían mucho más legibles si estuviera permitido. Principalmente 'auto foo_ = Tipo {...};', así que ese caso ya ayudaría. – akim

Cuestiones relacionadas