Is the behavior of the std :: container set during insertion?

When inserted into a set, does the set internally delete several objects several times? I tried to insert two objects of type MyClass, as in the following program, but, to my surprise, it calls the class destructor with the value 2 times originally inserted! I can not understand any logic of this. Can someone give an idea of ​​the exit? (in bold)

#include<stdio.h> #include<stdlib.h> #include<set> using namespace std; struct MyClass { double num; ~MyClass() { printf("Destructor called..for val: %lf\n", num); } }; typedef int (*fun_comp)(MyClass, MyClass); int comp(MyClass a, MyClass b) { return a.num-b.num; } int main() { fun_comp fptr; fptr = &comp; set<MyClass, int (*)(MyClass, MyClass)> b(fptr); for(int i=3; i< 5; i++) { printf("started with i: %d....\n\n", i); { MyClass m; m.num=i*1.134; b.insert(m); printf("Inserted val: %lf\n", m.num); } printf("ended....\n\n"); } printf("Done with insert..\n"); return 0; } 

output: started with i: 3 ....

Box val: 3.402000

Destructor called ... for val: 3.402000

over ....

started with i: 4 ....

Destructor called ... for val: 4.536000 <------- why is this freed before insertion

The destructor invoked ... for val: 3.402000 <------- multiple invocation of the destructor for this significant object

Destructor called ... for val: 4.536000 <-------- ??

Destructor called ... for val: 3.402000 <------ again !!

Box val: 4.536000

Destructor called ... for val: 4.536000

over ....

Done with the insert.

Destructor called ... for val: 3.402000

Destructor called ... for val: 4.536000

+4
source share
3 answers

Comparator

 int comp(MyClass a, MyClass b) { return a.num-b.num; } 

takes its parameters by value. This will create additional copies, which will then be destroyed.

Link passing will work better.

+11
source

Change the comparison function to use (const) links

 int comp(const MyClass& a, const MyClass& b) { return a.num-b.num; } 

Each time you call your comp, it creates copies of a and b. These copies are destroyed when commands are issued.

+11
source

In addition to the points above, your comparison function is not valid because it does not define a consistent order of values. If a.num = 1 and b.num = 2, then comp (a, b) is true, which means that “precedes” b, and comp (b, a) is also true, which means that b “precedes”, This makes the set behavior undefined.

It’s better to create a smaller statement for MyClass, and let the comparison function <> default do the work: struct MyClass {double num;

  ~MyClass() { printf("Destructor called..for val: %lf\n", num); } bool operator < (const MyClass &rhs) const { return num < rhs.num; } }; ... set<MyClass> b; 
+4
source

All Articles