7 Stimmen

Ist es okay, Konstruktoren zu verwenden, um einen 2D-Vektor als Einzeiler in C++ zu initialisieren?

Ist es in Ordnung, einen 2D-Vektor auf diese Weise zu initialisieren (hier alle Werte in einem 5x4 2D-Vektor sind auf 3 initialisiert)?

std::vector<std::vector<int> > foo(5, std::vector<int>(4, 3));

Dies scheint sich gut zu verhalten, aber überall, wo ich im Web nachsehe, scheinen die Leute zu empfehlen, einen solchen Vektor mit for-Schleifen und push_back() zu initialisieren. Ich hatte anfangs die Befürchtung, dass alle Zeilen hier auf denselben Vektor zeigen würden, aber das scheint nicht der Fall zu sein. Übersehe ich etwas?

10voto

Erik Punkte 85308

Dies ist absolut gültig - Sie erhalten einen 2D-Vektor ([5, 4] Elemente) mit jedem Element auf 3 initialisiert.

Für die meisten anderen Fälle (in denen Sie z. B. unterschiedliche Werte in verschiedenen Elementen haben wollen) können Sie keinen Einzeiler verwenden - und benötigen daher Schleifen.

3voto

AnT Punkte 300728

Nun, der Code ist gültig und tut tatsächlich das, was Sie wollen (vorausgesetzt, ich habe Ihre Absicht richtig verstanden).

Allerdings ist diese Vorgehensweise im Allgemeinen ineffizient (zumindest in der aktuellen Version der Sprache/Bibliothek). Die obige Initialisierung erzeugt einen temporären Vektor und initialisiert dann einzelne Untervektoren durch Kopieren von das Original. Das kann ziemlich ineffizient sein. Aus diesem Grund ist es in vielen Fällen vorzuziehen, den Top-Level-Vektor selbst zu konstruieren

std::vector<std::vector<int> > foo(5);

und dann darüber iterieren und die einzelnen Untervektoren an Ort und Stelle aufbauen, indem man etwas tut wie

foo[i].resize(4, 3);

1 Stimmen

Der Preis für den Einzeiler-Ansatz ist die Konstruktion eines einzigen inneren temporären Vektors - also nicht sehr ineffizient IMO.

1 Stimmen

@Erik: Konstruktion und Zerstörung. Aber nicht nur das. Die Kosten umfassen auch die Kosten für die Initialisierung durch Kopieren von Vektor zu Vektor, im Gegensatz zu den Kosten für das Kopieren von Element zu Vektor bei der In-Place-Konstruktion. Bei primitiven Typen ist der Unterschied sogar qualitativ.

1 Stimmen

So wie ich es sehe, wird die Kopiersektor-Variante auf eine Reihe von memcpy-äquivalenten Aufrufen hinauslaufen, während die Schleifen eine Reihe von memset-äquivalenten Aufrufen auswerten werden. Zumindest wenn der Compiler etwas optimiert. Ja, memcpy könnte als teurer angesehen werden als memset - aber da die Quelldaten vermutlich im Cache sind und die Zieldaten vermutlich nicht, glaube ich nicht, dass es in diesem Szenario praktische Unterschiede gibt. Wären die Vektoren größer oder würden sie komplexe Objekte enthalten, wäre das sicher der Fall, aber für seine Ints ist die Lesbarkeit besser. Ihr Punkt ist durchaus gültig, obwohl, die Kopie ctor peut ineffizienter sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X