std::string in gcc nicht move_assignable
-
Weiß jemand, warum sich der GCC 4.9 bei std::string nicht an den Standard (http://en.cppreference.com/w/cpp/string/basic_string/operator%3D) hält und std::string zwar move_constructable aber nicht move_assignable ist?
Auf dieser Seite
http://en.cppreference.com/w/cpp/types/is_move_assignable
liefert der GCC das das beschriebene Ergebnis.Ein MWE:
#include<string> int main(void) { static_assert(std::is_nothrow_move_assignable<BigFuryObject>::value, "should not fail"); }bzw. http://coliru.stacked-crooked.com/a/cc36c1ac68529605
BTW, auf clang funktioniert das.
-
Das MWE sollte so sein:
#include<string> int main(void) { static_assert(std::is_nothrow_move_assignable<std::string>::value, "should not fail"); }
-
"move assignable" != "nothrow move assignable"
Der Grund könnte sein, dass es bei "move construction" nix freizugeben gibt, bei "move assignment" aber u.U. schon.
Der String der per "move assignment" einen neuen Wert zugewiesen bekommt, könnte ja Resourcen besitzen. Die müssen dann entweder dem "Opfer" rübergeswapped oder direkt freigegeben werden.
Diese Operationen könnten man zwar vermutlich auch nothrow bekommen. Aber wenn sie es (warum auch immer) nicht sind, dann würde das wohl dazu führen dass der move op = nicht nothrow ist. Auf den move ctor hätte es aber keinen Einfluss.
-
Aber warum ist es im standard als noexcept deklariert und warum kann es der clang?
-
Im Standard ist es vermutlich mit
noexceptmarkiert, weil man esnoexceptmachen kann.
Was ich ja aucherwähntangedeutet habe.Warum es bei GCC nicht
noexceptist, kann ich die nicht sagen. Ich kann nur die bereits beschriebene Vermutung anbieten, dass es irgendwas mit der Freigabe der Resourcen zu tun hat.Wenn du es genau wissen willst guck doch einfach in die Implementierung.
-
Soweit ich weiß, ist der std::string im GCC immer noch einer mit COW-Optimierung (die nach dem neuen Standard quasi verboten ist) und die SSO ist noch experimentell und muss explizit aktiviert werden. Ich mag das gerade nicht komplett durchdenken, was da wann werfen kann, aber es könnte damit zu tun haben.
-
Das ist schon vor zwei Jahren als Bug #58265 gemeldet worden. Jedoch scheint es als ob hier ein Defekt vorliegt der momentan als aktives LWG-issue 2063 behandelt wird.
Kurioserweise wurde das erst vor einigen Tagen angefasst. Der aktuelle working draft enthält jedoch etwas anderes als die proposed resolution:
basic_string& operator=(basic_string&& str) noexcept(allocator_traits<Allocator>::propagate_on_container_move_assignment::value || allocator_traits<Allocator>::is_always_equal::value);
-
Bleibt die Frage warum std::allocator nicht "is_always_equal" ist.
Oder hab ich da was falsch verstanden?
-
Ziemlich witzig und passt soweit ich mich erinnere zum Thema:
https://www.youtube.com/watch?v=BezbcQIuCsY
So um Minute 30.