2012-07-30 6 views
5

Unser Team lief in das gleiche Problem hier http://forums.codeguru.com/archive/index.php/t-514404.html beschrieben, das heißt some_vec.resize(new_size) Aufruf, wo N = new_size - some_vec.size() mit N> = 2 und VC10 default-konstruierte alle neuen Elemente N, während GCC standardmäßig ein einzelnes Element, wie das Prototyp Element konstruiert , um es N-mal für die neuen Elemente zu kopieren.Wie oft sollte std :: vector :: resize standardmäßig neue Elemente konstruieren?

Da dies ein Vektor von UUID ist, wo der Standardkonstruktor jede neue Instanz zufällig initialisiert, haben wir am Ende N-mal die gleiche UUID mit GCC und N verschiedene UUIDs mit VC. Das war genug, um in unserer Test-Suite auf einer Plattform, aber nicht in einer anderen zu verheeren, und es machte keinen Spaß, sie zu finden.

Meine Frage ist also: wer Recht hat? VC oder GCC? Oder ist das eine der geliebten Ecken von C++, die nicht spezifiziert ist? TIA, --DD

+1

Der Standard hat sich geändert. Hier ist eine ähnliche Frage [std :: vector, Standardkonstruktion, C++ 11 und Brechen changes] (http://stackoverflow.com/questions/5759232/stdvector-default-construction-c11-and-breaking-changes) –

+0

Es sollte angemerkt werden, dass Ihre Klasse ein bisschen "komisch" ist: Grundsätzlich haben Sie die Situation wo für 'T x; T y; 'Sie haben' x! = Y'. Dies garantiert eine Menge extra Pflege und explizite Dokumentation ... –

+0

Randomisierung auf dem Bau ist eine schlechte Sache, können Sie es in Ihrem Beispiel sehen. Der meiste Code geht davon aus, dass alle standardmäßig konstruierten Objekte gleich sind. Um diese Probleme zu lösen, sollten Sie eine Randomisierungsfunktion haben. Oder eine Fabrik, die randomisierte Objekte erzeugt. – Dani

Antwort

6

Ich wette, wenn Sie GCC mit -std=c++0x kompilieren, erhalten Sie das gleiche Ergebnis wie mit MSVC, das heißt, die N Standardkonstruktionen. Dies hat sich in C++ 11 geändert, siehe here. Es gibt jetzt zwei Überladungen, eine mit nur der neuen Größe, die standardmäßig die neuen Elemente erstellt, und eine andere, die einen "Prototyp" -Parameter verwendet, aus dem jedes neue Element kopiert werden kann.

Nun, um konsistente Ergebnisse zu erhalten, egal in welchem ​​Modus Sie kompilieren, benutzen Sie einfach

v.resize(new_size, T()); 

Hintergrund: Die Änderung war notwendig, da es jetzt Typen sind, die beweglich sein kann, aber nicht kopierbar (wie std::unique_ptr). Die alte Signatur verlangte Kopierbarkeit. Jetzt muss der erste Template-Parameter für Standard-Containertypen nur kopierbar sein, wenn Sie Operationen verwenden, die eine Kopie erfordern.

Verwandte Themen