Verrücktes std::set::insert
-
#include <set> #include <iostream> struct MyPair { int a; int b; MyPair(int a = 0, int b = 0) : a{a} , b{b} { } friend constexpr bool operator<(MyPair const& lhs, MyPair const& rhs) { return lhs.a < rhs.a; } }; int main() { std::set <MyPair> s; s.insert({2, 3}); // Was gibt es hier aus? std::cout << s.size() << "\n"; s.clear(); s.insert(MyPair{2, 3}); // und hier? std::cout << s.size() << "\n"; }
Sch*** Standard, dass std::set mit std::initializer_list überladen wird.
Mit std::initializer_list überladen ist IMMER falsch.Was haltet ihr davon?
-
Wenn ich die default werte des Konstruktors entferne kommt bei beiden 1 raus.
Ich sehe da kein Problem des standards.
-
Soll das ein Rätsel sein?
-
@firefly
Im Beispiel sind die default dumm, aber nötig für das Beispiel. Mein Konstruktor ist aber überladen Mit jeweils einem oder 2 Params. Und ich habe nicht vor das zu ändern.@manni66
In komplexerem Code ist das nicht offensichtlich, dass das passiert.So wie es ist, ist es unituitiv. Einfach ein schlechtes Klassen Interface. Es ist einfach falsch zu machen #Meyers.
-
Wenn du unbedingt das alte verhalten haben willst dann musst du den code als c++03/c++98 übersetzen lassen.
Oder du verwendest die neuen features wodurch man eine kopie beim insert vermeiden kann.
Denn bei deinem Beispiel-code wird in beiden fällen ein temporäres objekt erzeugt, welche dann in das set kopiert wird.Mit C++11 lässt sich die kopie vermeiden in dem man statt std::insert std::emplace verwendet:
#include <set> #include <iostream> struct MyPair { int a; int b; MyPair(int a = 0, int b = 0) : a(a) , b(b) { std::cout<<"ctor"<<std::endl; } MyPair(const MyPair&) { std::cout<<"copy-ctor"<<std::endl; } MyPair(MyPair&&) { std::cout<<"move-ctor"<<std::endl; } friend constexpr bool operator<(MyPair const& lhs, MyPair const& rhs) { return lhs.a < rhs.a; } }; int main() { std::set <MyPair> s; s.emplace(2, 3); // << Hier wird nur ein objekt implace im set erzeugt // Was gibt es hier aus? std::cout << s.size() << "\n"; s.clear(); s.emplace(MyPair{2, 3}); // << Hier wird immer noch kopiert // und hier? std::cout << s.size() << "\n"; }
-
Ja ich bin eh schon auf emplace umgestiegen.
Kann er aus dem insert(xvalue) nicht in einem Kontruktor ohne Seiteneffekte die konstruktion inplace machen?