2012-07-30 10 views
5

La nostra squadra appena incontrato lo stesso problema descritto qui http://forums.codeguru.com/archive/index.php/t-514404.html, cioè chiamando some_vec.resize(new_size), dove N = new_size - some_vec.size() con N> = 2, e VC10 default-costruito tutti gli elementi nuovi N, mentre GCC di default costruito un singolo elemento, come il prototipo elemento , per copiarlo-costruirlo N volte per i nuovi elementi.Quante volte std :: vector :: resize dovrebbe default-costruire nuovi elementi?

Poiché questo è un vettore di uuid, dove il costruttore predefinito inizializza a caso ogni nuova istanza, abbiamo finito con N volte lo stesso uuid con GCC e N uuid diversi con VC. Questo è stato sufficiente a provocare il caos nella nostra suite di test su una piattaforma ma non un'altra, e non è stato divertente da trovare.

La mia domanda è quindi: chi ha ragione? VC o GCC? O è uno di quegli amati angoli del C++ che non è specificato? TIA, --DD

+1

Lo standard è cambiato. Ecco una domanda simile [std :: vector, costruzione predefinita, C++ 11 e interruzioni di modifica] (http://stackoverflow.com/questions/5759232/stdvector-default-construction-c11-and-breaking-changes) –

+0

Va notato che la tua classe è un po '"strana": fondamentalmente, hai la situazione in cui per 'T x; T y; 'hai' x! = Y'. Ciò garantisce molta cura in più e documentazione esplicita ... –

+0

La casualità nella costruzione è una brutta cosa, puoi vederla nel tuo esempio. La maggior parte del codice presuppone che tutti gli oggetti costruiti di default siano uguali. Per risolvere questi problemi dovresti avere una funzione randomizzante. O una fabbrica che crea oggetti randomizzati. – Dani

risposta

6

Scommetto che se si compila GCC con -std=c++0x, si otterrà lo stesso risultato di MSVC, ovvero le costruzioni N predefinite. Questo è cambiato in C++ 11, vedi here. Ora ci sono due overload, uno con solo la nuova dimensione che default costruisce i nuovi elementi, e un altro che accetta un parametro "prototype" per copiare-costruire ogni nuovo elemento.

Ora, per ottenere risultati coerenti indipendentemente dalla modalità si compila in, basta usare

v.resize(new_size, T()); 

informazioni Contesto: Il cambiamento era necessario, dal momento che ora ci sono tipi che possono essere mobili, ma non copiabile (come std::unique_ptr). La vecchia firma richiedeva la riproducibilità. Ora il solo parametro del template per i tipi di container standard è richiesto solo per essere copiato, se si utilizzano operazioni che richiedono una copia.