Questo semplicemente non dovrebbe funzionare. Al §23.1 ¶ 3 è specificato, come hai detto, che gli oggetti memorizzati in un contenitore devono essere CopyConstructible
(come specificato al §20.1.3) e Assignable
.
I requisiti Assignable
per un tipo T
sono che, essendo t
e u
di tipo T
, si può fare:
t = u
avere un T&
come valore di ritorno e t
equivalente a u
come postcondition. (§23.1 ¶4)
Così, const
tipi sono chiaramente non Assignable
, dal momento che facendo t = u
solleverebbe un errore di compilazione (§7.1.5.1 ¶5).
Suppongo che si tratti di un bug nell'implementazione di Microsoft. g ++ su Linux emette il tipico errore di modello di linee da 25 kajillion se si tenta anche di istanziare un vector<const int>
(testato con e senza il flag -std=c++0x
, per ogni evenienza).
A proposito, questo è anche spiegato in dettaglio in questo IBM FAQ.
In teoria, come ha detto @James McNellis, il compilatore non è tenuto a saltare sul instantiation vettore (se si tratta di qualcosa di indefinito comportamento può accadere - tra cui tutto funziona bene); tuttavia, nella dichiarazione di assegnazione c'è una violazione dello standard che dovrebbe produrre un errore di compilazione.
In effetti, il membro operator[]
restituisce un vector<const int>::reference
; quello è richiesto per essere un lvalue di T
(§23.1 ¶5 tabella 66); poiché T
è di tipo const
, sarà un valore di const
. Quindi cadiamo in (§7.1.5.1 ¶5), che definisce il codice che tenta di eseguire un'assegnazione ad un elemento const
come "mal formato", e ciò richiede un errore di compilazione o almeno un avvertimento, perché l'assegnazione a - const
è una regola diagnosticabile (§1.4 ¶1-2) (non è stata specificata alcuna istruzione "non è richiesta alcuna diagnostica").
montaggio finale
In realtà, @James McNellis è giusto; una volta che hai invocato il comportamento non definito istanziando vector<const int>
, le normali regole smettono di avere valore, quindi l'implementazione è ancora conforme agli standard qualunque cosa faccia, inclusa la rimozione dello const
dal tipo di elemento o la generazione dei soliti demoni nasali.
Non solo: VS 2010 consente di * assegnare nuovi valori * a 'v [0]'. Provalo! –
Sono curioso di ciò che VC fornisce per typeid (vector :: value_type) .name() (e lo si confronta con typeid (vector :: value_type) .name() o demanglo esso). –
Uno e lo stesso: 'int'. –