Move-Semantik std::vector
-
Hallo, ich stoße mit der VC++2013 ctp gerade auf folgendes Problem:
class test { public: test(test && other) {} private: test(const test& other); }; std::vector< test > testvector;1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0(622): error C2248: 'prop::detail::dual_node::test::test' : cannot access private member declared in class 'prop::detail::dual_node::test'Ersteinmal gehe ich natürlich davon aus, dass ich hier etwas falsch mache. Aber mir fällt nicht auf, inwiefern, und viele Orte gibt es ja irgendwie nicht, wo etwas schief laufen kann.
Nun habe ich gelesen, dass man den move-Konstruktor explizit als noexcept angeben muss, damit vector Move-Semantik benutzen darf. Das Problem ist allerdings, dass VC++ gar kein noexcept unterstützt und throw() hilft auch nicht.Wäre für Hilfe sehr dankbar!
-
VC++ ist der letzte Dreck auf Erden, mehr musst du nicht wissen.
Nun habe ich gelesen, dass man den move-Konstruktor explizit als noexcept angeben muss, damit vector Move-Semantik benutzen darf.
Nein, das ist falsch: Weder MoveAssignable noch MoveConstructible (die Konzepte die
vectorbspw. voraussetzt) fordernnoexcept.
-
Grummel, ich hab's!
Irgendwie ging ich gerade nicht davon aus, dass man auch den move operator= benötigen würde -.-
-
moveit schrieb:
Grummel, ich hab's!
Irgendwie ging ich gerade nicht davon aus, dass man auch den move operator= benötigen würde -.-Ach Moment! Zeig uns doch wenigstens den Code, der die Fehlermeldung verursacht! Ich dachte, lediglich die Deklaration eines vectors mit deinem Typ würde die Fehlermeldung verursachen. Da habe ich VC++ zu Unrecht gerügt. Egal, verdient es sowieso.
-
Der Code da oben war genau der herunterminimierte Code, der zu der Fehlermeldung führt.
Ich habe dort einfach nicht beachtet, dass vector auch MoveAssignable benötigt, was dann bei fehlendem operator= zu der Fehlermeldung führte.
Wenn ich operator=(test&&); einbaue, dann klappt's.
-
moveit schrieb:
Der Code da oben war genau der herunterminimierte Code, der zu der Fehlermeldung führt.
Dann ist VC++ doch Scheiße.
vectorerfordert standardmäßig nichts, schon rein aus Kompabilitätsgründen wäre das lächerlich (wie viel alter Code deklariert einen Move-Ctor?!). Nur bestimmte Operationen erfordern bestimmte Konzepte.
-
Sone schrieb:
VC++ ist der letzte Dreck auf Erden, mehr musst du nicht wissen.[...]
Dann ist VC++ doch Scheiße.Jaja, Sone. Eines Tages wirst selbst du mal über deinen kleinen Tellerrand blicken.
-
@Sone
VS ist nicht nur C++ compiler, da steckt sehr viel mehr drin, und es ist generell ein sehr gutes tool. hast wieder mal nix kapiert. derp
-
Nexus schrieb:
Sone schrieb:
VC++ ist der letzte Dreck auf Erden, mehr musst du nicht wissen.[...]
Dann ist VC++ doch Scheiße.Jaja, Sone. Eines Tages wirst selbst du mal über deinen kleinen Tellerrand blicken.
Ich rede nicht von der IDE! Die IDE ist super. Der Debugger ist gut. Der Compiler ist nur doof. Wer mag denn den Compiler? Der ist furchtbar, alle finden den doof!
VS ist nicht nur C++ compiler
Ja, VS! Nicht VC++! VS kompensiert das ganze mehr als genug mit einer super IDE.
-
moveit schrieb:
Der Code da oben war genau der herunterminimierte Code, der zu der Fehlermeldung führt.
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.20617.1 schrieb:
1>------ Rebuild All started: Project: blub, Configuration: Debug x64 ------
1> main.cpp
1> blub.vcxproj -> D:\blub\x64\Debug\blub.exe
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
-
Sone schrieb:
Nun habe ich gelesen, dass man den move-Konstruktor explizit als noexcept angeben muss, damit vector Move-Semantik benutzen darf.
Nein, das ist falsch: Weder MoveAssignable noch MoveConstructible (die Konzepte die
vectorbspw. voraussetzt) fordernnoexcept.Nunja, es ist eigentlich sinnvoll copy statt move zu benutzen, um eine starke Garantie bei exceptions von push_back und emplace_back und ähnliche zu gewährleisten.
Beispiel:
#include <iostream> #include <vector> class movable { public: movable() {} movable(movable const&) {std::cout << "why no move?\n";} movable(movable&&) {} movable& operator =(movable const&) {std::cout << "why no move?\n";return *this;} movable& operator =(movable&&) {return *this;} }; int main() { std::vector<movable> vec(3); vec.emplace_back(); }Kompiliert mit GCC 4.8.1, -std=c++11, ausgabe:
why no move?
why no move?
why no move?Fügt man allerdings noexcept ein, ist die Ausgabe leer. Natürlich, wenn der Type kein Kopieren unterstützt, dann wird nur move genutzt.
-
Ich tippe mal darauf, dass die Container std::move_if_noexcept verwenden.
-
Sone schrieb:
VS ist nicht nur C++ compiler
Ja, VS! Nicht VC++! VS kompensiert das ganze mehr als genug mit einer super IDE.
Bitte lerne doch erst einmal, was Visual C++ überhaupt ist, bevor du dagegen stänkerst.
-
Ihr scheint ein anderes Visual C++ zu haben als ich. Der Editor und Intellinonsense sind furchtbar. Der Debugger ist furchtbar. Die Einstellungsdialoge sind furchtbar. Die Performance ist furchtbar. Die Optik ist seit 2012 furchtbar. Die Fehlermeldungen des Compilers sind furchtbar. Die Anzeige dieser Fehlermeldungen in der IDE ist furchtbar. Die Unterstützung von C++ ist furchtbar, auch in 2013 noch. Die Unterstützung von C ist furchtbar.
Also unterm Strich eine "super IDE".
-
TyRoXx schrieb:
furchtbar furchtbar furchtbar
mimimi
VS ist immer noch die beste IDE für C++, besonders mit VAX. Klar, der neue Look ist nicht so toll, aber den kann man ja ändern. Wo ansonsten hast du so gute semantische Codeanalyse, Debugger oder Profiler? Arbeite mal mit Code::Blocks, dann lernst du die Bedeutung von "furchtbar" wirklich kennen

-
mi schrieb:
VS ist immer noch die beste IDE für C++, besonders mit VAX.
Das wichtigste Feature, den C++ Editor, muss man von einer anderen Firma dazu kaufen. Das bestätigt natürlich die enorme Qualität von Visual C++ an sich.
-
TyRoXx schrieb:
Das wichtigste Feature, den C++ Editor, muss man von einer anderen Firma dazu kaufen. Das bestätigt natürlich die enorme Qualität von Visual C++ an sich.
Ich brauche den Editor von VS schon seit Jahren und bin absolut zufrieden damit. Und damit bin ich ganz sicher nicht der einzige. Linux-Fanboys bleiben vielleicht besser bei ihrem Emacs und Vim. Man kann zwar damit alle möglichen Textverarbeitungsoperationen durchführen, aber etwas tatsächlich Nützliches wie Autovervollständigung oder semantische Analyse in Echtzeit muss man sich, wenn überhaupt, durch separate Tools einbauen. Von grafischem Debugger will ich gar nicht anfangen.
Was Leute immer vergessen, ist dass das tatsächliche Code-Schreiben nur einen Teil der Entwicklungszeit ausmacht. Dinge wie Dokumentation lesen und schreiben, Debuggen, Profilen oder Testen gehört auch dazu. Und hier unterstützt VS zumindest mich gewaltig. Aber als Boilerplatecoder braucht man diese Tools vielleicht nicht...
-
TyRoXx schrieb:
Der Editor und Intellinonsense sind furchtbar.
Der Editor ist sicher nicht der beste, aber sicher auch nicht der schlechteste...
TyRoXx schrieb:
Der Debugger ist furchtbar.
Zeig mir einen besseren C++ Debugger.
TyRoXx schrieb:
Die Performance ist furchtbar.
aha
TyRoXx schrieb:
Die Optik ist seit 2012 furchtbar.
subjektiv
TyRoXx schrieb:
Die Fehlermeldungen des Compilers sind furchtbar.
Der einzige mir bekannte Compiler, der wirklich bessere Fehlermeldungen liefert, ist clang...
TyRoXx schrieb:
Die Anzeige dieser Fehlermeldungen in der IDE ist furchtbar.
inwiefern?
TyRoXx schrieb:
Die Unterstützung von C++ ist furchtbar, auch in 2013 noch.
Gibt echt schlimmeres.
TyRoXx schrieb:
Die Unterstützung von C ist furchtbar.
Nenn mir bitte einen vernünftigen Grund, C99 zu benutzen statt C++, generell, insbesondere auf dem PC und insbesondere unter Windows...
-
Also bei mir Arbeit mit Eclipse (und dem GCC) kennt der nichtmals assert im Editor, das wird immer rot angestrichen und autovervollständigt wirds auch nicht. (Obwohl es legitimer C++ Code ist, der auch vom Compiler geschluckt wird).
Und wenn die Performance bei dir schlecht ist, dann solltest du vielleicht mal über einen neuen Rechner nachdenken. Auf meinem Quadcore mit mehr als 4 GB Ram läuft das super. (Wobei wenn ich die Klassenansicht expandiert habe und schreibe, dann arbeitet der schon sehr hart und ist langsam. Aber sobald die zu ist, alles n1)
Ok, die Intellisense und die Autovervollständigung hakt manchmal. Mit einer kompletten templatebasierten Library und überall auto und decltype Keywords. Alles andere geht super (und wenn nicht, wartet man ne Sekunde bis der alles geprüft hat, dann gehts).
Und die C++11 unterstützung muss man wenigstens nicht mit Special-Parametern wie -pthread nach zum laufen überreden.
-
Sone schrieb:
Nun habe ich gelesen, dass man den move-Konstruktor explizit als noexcept angeben muss, damit vector Move-Semantik benutzen darf.
Nein, das ist falsch:
So falsch ist das nicht.
Sone schrieb:
Weder MoveAssignable noch MoveConstructible (die Konzepte die
vectorbspw. voraussetzt) fordernnoexcept.Das stimmt, tut hier aber nichts zur Sache.
Kellerautomat schrieb:
Ich tippe mal darauf, dass die Container std::move_if_noexcept verwenden.
Richtig, std::vector<> verwendet std::move_if_noexcept statt std::move an einigen Stellen. Das tut es, damit z.B. vector<>::resize in den Fällen, wo es möglich ist, die "strong exception guarantee" geben kann. Wenn also T einen Movekonstruktor hat, der nicht noexcept ist, T dafür aber auch kopierbar ist, dann wird beim Vergrößern des Vektors doch kopiert; denn sonst könnten Daten verloren gehen, wenn ein Move-Konstruktor dabei eine Ausnahme schmeißt. Ist T nicht kopierbar, geht es ja nicht anders. Dann hat man bei resize aber auch keine starke Ausnahmesicherheit mehr.