Esto simplemente no debería funcionar. En §23.1 ¶ 3 se especifica, como usted dijo, que los objetos almacenados en un contenedor deben ser CopyConstructible
(como se especifica en §20.1.3) y Assignable
.
Los requisitos para un tipo Assignable
T
son que, al ser t
y u
de tipo T
, que puede hacer:
t = u
tener un T&
como valor de retorno y t
equivalente a u
como condición posterior. (§23.1 ¶4)
Por lo tanto, const
tipos son claramente no Assignable
, ya que de t = u
levantaría un error de compilación (§7.1.5.1 ¶5).
Supongo que esto es un error en la implementación de Microsoft. g ++ en Linux emite el típico error de plantilla de 25 kajillion-lines si incluso intentas instanciar un vector<const int>
(probado con y sin el indicador -std=c++0x
, por las dudas).
Por cierto, esto también se explica en detalle en este IBM FAQ.
En teoría, como dijo @ James McNellis, no se requiere el compilador para hacer estallar en la creación de instancias de vectores (si se trata de un comportamiento indefinido puede pasar cualquier cosa - incluyendo todo funcionando muy bien); sin embargo, en la declaración de asignación hay una violación de la norma que debería producir un error de compilación.
De hecho, el miembro operator[]
devuelve vector<const int>::reference
; se requiere que sea un valor l de T
(§23.1 ¶5 tabla 66); ya que T
es del tipo const
, será un valor const
lvalue. Así que nos limitamos a (§7.1.5.1 ¶5), que define el código que intenta realizar una asignación a un elemento const
como "mal formado", y esto exige un error de compilación o al menos una advertencia, porque la asignación a - const
es una regla diagnosticable (§1.4 ¶1-2) (no se especifica la declaración "no se requiere diagnóstico").
edición final
En realidad, @ James McNellis es correcto; una vez que ha invocado un comportamiento indefinido al crear instancias de vector<const int>
, las reglas habituales dejan de tener valor, por lo que la implementación sigue cumpliendo los estándares, haga lo que haga, incluida la eliminación del const
del tipo de elemento o la generación de los demonios nasales habituales.
No solo eso - VS 2010 le permite * asignar nuevos valores * a 'v [0]'. ¡Intentalo! –
Tengo curiosidad por lo que VC da para typeid (vector :: value_type) .name() (y o bien lo compara con typeid (vector :: value_type) .name() o demangle it). –
Uno y el mismo: 'int'. –