std::vector befüllen ohne copy constructor?
-
swap
-
std::move?
Direkt mit Vektorelementen arbeiten?
-
-
-
-
Ohne C++11 willst du eh kein C++ benutzen, dann nimm lieber [beliebige andere Sprache].
-
cooky451 schrieb:
Ohne C++11 willst du eh kein C++ benutzen, dann nimm lieber [beliebige andere Sprache].
Äh.. Ja.
Vlt wird es mir auch so gehen wenn ich c++11 benutzt habe, aber derzeit komme ich auch mit "normalem" c++ zurecht.
Btw. warum ist c++11 wenn es so viel bietet noch kein Standard in allen SDKs? Das 11. gibts doch schon ne Weile.nwp3 schrieb:
Dankesehr.
-
cl90 schrieb:
cooky451 schrieb:
Ohne C++11 willst du eh kein C++ benutzen, dann nimm lieber [beliebige andere Sprache].
Äh.. Ja.
Vlt wird es mir auch so gehen wenn ich c++11 benutzt habe, aber derzeit komme ich auch mit "normalem" c++ zurecht.
Btw. warum ist c++11 wenn es so viel bietet noch kein Standard in allen SDKs? Das 11. gibts doch schon ne Weile.Gibts doch schon. Das ist eine Sache des Compilers, d.h. bei einem aktuellen Compiler kannst du all die schönen Dinge machen.
Wenn du externe Bibliotheken nutzt, kann es dir erstmal egal sein, wie die funktionieren. Prinzipiell sind (sollten) die gut getestet sein und auch eine ordentliche Performance (zumindest im Release Modus*) haben. Denn die ganzen C++11 Neuerungen einzupflegen ist en gutes Stück Arbeit. Zumal es auch fraglich ist, ob eine Refaktorisierung was bringt. Einzig Move-Semantics und RValue-Referenzen bringen Performance**.
Wenn du aber neuen Code schreibst, dann lohnt es sich sehr stark C++11 zu nutzen, da das Codeschreiben dadurch schon flotter wird, wie ich finde.*: Ich erinnere mich da an SFML. Im Debug Modus lief mein Game mit 0.5 - 2 FPS, im Release mit über 400
**: Das ist eine harte Aussage, aber so nicht gemeint. C++11 bringt schon viel, aber ich zweifle an, dass eine komplette Refaktorisierung eines großen Codestücks so viel Nutzen bringt. RValues bringen der Performance noch was, aber alles andere dürfte nur Syntax Zucker sein, oder?
-
alles andere dürfte nur Syntax Zucker sein, oder?
range-based for?
-
Ja, sag ich doch.
Das ist doch "nur" eine Kurzschreibweise für
for(auto it = std::begin(cont); it != std::end(cont); ++it){}
(oder ähnliches)
oder verstehe ich da was falsch?Aber wo ist da durch den Standard definiert, dass es einen Performanceboost gibt?
-
Skym0sh0 schrieb:
Einzig Move-Semantics und RValue-Referenzen bringen Performance**.
…
**: Das ist eine harte Aussage, aber so nicht gemeint. C++11 bringt schon viel, aber ich zweifle an, dass eine komplette Refaktorisierung eines großen Codestücks so viel Nutzen bringt. RValues bringen der Performance noch was, aber alles andere dürfte nur Syntax Zucker sein, oder?
Es war schon vorher in C++ möglich, verflixt schnelle Programme zu basteln. Es war auch schon in C möglich, sogar in Assembler. Allein es ist in C angenehmer als in Assembler, in altem C++ viel angenehmer als in C, und in C++11 (vor allem wegen range based for) angenehmer als in altem C++.
-
Ja, das stimmt.
-
Skym0sh0 schrieb:
(oder ähnliches)
Und hier liegt der Hund begraben: Der end-Iterator wird bei deiner Schleife potenziell in jedem Durchlauf angefordert, während bei range-based for dieser (hier
__end
) zwischengespeichert wird:{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
Darüber hatten wir hier auch schon mal einen Thread.
-
@Arcoth: Stimmt. Trotzdem wählen Leute die Range-Based For primär wegen der Syntax. Dass dabei die Performance leicht besser sein kann, ist eher ein netter Nebeneffekt, vielen Entwicklern dürfte das gar nicht bekannt sein.
-
cooky451 schrieb:
Ohne C++11 willst du eh kein C++ benutzen, dann nimm lieber [beliebige andere Sprache].
So langsam muss man hier wirklich darauf achten, welche Antworten man ernst nehmen kann und welche nicht.
-
cl90 schrieb:
Wie kann man einen std::vector befüllen ohne das ein copy constructor aufgerufen wird? möglichst ohne etwas auf den Heap zu laden.
Ich würde gerne folgende Zeile, die noch einen copy constructor aufruft, austauschen.vector.push_back(QSubPlotable(&m_ColPattern, &m_FGWidthOffset))
Wie immer: Mehr Information wär nett gewesen. Aber ich rate mal, dass
QSubPlotable
ein Typ und keine Funktion ist und dass Deinevector
-Variable vom Typvector<QSubPlotable>
ist.Um etwas direkt in verschiedenen Containern zu erzeugen, ohne da etwas reinkopieren zu müssen, wurde in C++11
emplace
hinzugefügt:vector.emplace_back(&m_ColPattern, &m_FGWidthOffset);
Super wär's jetzt noch, wenn
QSubPlotable
movable würde (falls es das nicht schon ist). Dann könnte sich so ein Vektor auch relativ effizient vergrößern. Ansonnsten: Wenn du die Größe exakt kennst, kannst du natürlich auch vor den ganzen push/emplace_backs schonvector<>::reserve
aufrufen.Wenn ein
QSubPlotable
jetzt etwas großes, unhandliches ist, was einen teuren Copy-Ctor und keinen Move-Ctor hat, könnte man es ja dann noch mit einer Indirektion versuchen, alsounique_ptr<QSubPlotable>
oder so.Auch wichtig: Den Kram messen, wenn es um Geschwindigkeit geht.
-
kkaw schrieb:
cl90 schrieb:
Wie kann man einen std::vector befüllen ohne das ein copy constructor aufgerufen wird? möglichst ohne etwas auf den Heap zu laden.
Ich würde gerne folgende Zeile, die noch einen copy constructor aufruft, austauschen.vector.push_back(QSubPlotable(&m_ColPattern, &m_FGWidthOffset))
Wie immer: Mehr Information wär nett gewesen. Aber ich rate mal, dass
QSubPlotable
ein Typ und keine Funktion ist und dass Deinevector
-Variable vom Typvector<QSubPlotable>
ist.Um etwas direkt in verschiedenen Containern zu erzeugen, ohne da etwas reinkopieren zu müssen, wurde in C++11
emplace
hinzugefügt:vector.emplace_back(&m_ColPattern, &m_FGWidthOffset);
Super wär's jetzt noch, wenn
QSubPlotable
movable würde (falls es das nicht schon ist). Dann könnte sich so ein Vektor auch relativ effizient vergrößern. Ansonnsten: Wenn du die Größe exakt kennst, kannst du natürlich auch vor den ganzen push/emplace_backs schonvector<>::reserve
aufrufen.Wenn ein
QSubPlotable
jetzt etwas großes, unhandliches ist, was einen teuren Copy-Ctor und keinen Move-Ctor hat, könnte man es ja dann noch mit einer Indirektion versuchen, alsounique_ptr<QSubPlotable>
oder so.Auch wichtig: Den Kram messen, wenn es um Geschwindigkeit geht.
Ich hab es jetzt letztendlich auf dem Heap gelöst. also
vector.pushback(new bla());
mit entsprechenden deletes an anderen stellen.
Danke für die Ausführung. Ich werde mir das zu einem späteren Zeitpunkt zusammen mit c++11 wieder ansehen.
-
cl90 schrieb:
Ich hab es jetzt letztendlich auf dem Heap gelöst. also
vector.pushback(new bla());
mit entsprechenden deletes an anderen stellen.Och nö! Der Ansatz ist sehr fehleranfällig bzgl Speicherlecks. Dann nimm doch wenigstens
boost::ptr_vector
, wenn du schon keine C++11 Features benutzen willst/kannst.
-
kkaw schrieb:
cl90 schrieb:
Ich hab es jetzt letztendlich auf dem Heap gelöst. also
vector.pushback(new bla());
mit entsprechenden deletes an anderen stellen.Och nö! Der Ansatz ist sehr fehleranfällig bzgl Speicherlecks. Dann nimm doch wenigstens
boost::ptr_vector
, wenn du schon keine C++11 Features benutzen willst/kannst.Ich bin auch nicht zufrieden damit...
Aber sag mir, kann ich mein Projekt ohne viel aufwand einfach auf C++11 umstellen?
Ich habe jetzt schon so viele externe Abhängigkeiten und weit mehr als 5000 Zeilen code in über 80 files... Ich weiß nicht wie einfach man das umstellen kann.
Ich habs mir vorerst nur auf meien ToCheck Liste für das nächste Projekt gesetzt.prt_vector regelt das delete selbst?
Weil das wäre kein Problem. Ich hab Boost x64 bereits im Projekt.
-
Du musst nichts umstellen (ausser vielleicht den Compiler), C++11 ist abwärtskompatibel -- von unbedeutenden Features mal abgesehen.
Ja,
boost::ptr_vector
räumt selbst auf. Ich persönlich bin aber spätestens seit C++11 kein Fan mehr von den Pointer-Containern, siehe hier.