Why does it work? std :: set find with search key and custom comparator

I do not understand why the following works (although I'm glad it works!):

I can define std::set objects with a custom comparator. This custom comparator works by comparing a member variable of two compared objects. BUT , then I can use the set .find(x) function with x , which has the type of a member variable, and not the object itself, and it works!

Here is a very simplified example:

my_class.h

 class my_class //just hold an integer { public: int an_int; my_class(int new_int) : an_int(new_int) { } //compare instances of this class by comparing their integers... struct compare_instances { bool operator() (const my_class &a, const my_class &b) const { return a.an_int < b.an_int; } }; }; 

main.cpp:

 ... std::set<my_class, my_class::compare_instances> my_class_set; my_class_set.insert( my_class(18) ); my_class_set.insert( my_class(7) ); my_class_set.insert( my_class(22) ); std::set<my_class, my_class::compare_instances>::const_iterator found_it = my_class_set.find(18); std::fprintf(stderr, "found_it->an_int = %d\n", found_it->an_int); 

Result: "found_it-> an_int = 18" !!!!!!

I would expect that the above code would not compile, but for the compiler to yell at me that " 18 not of type my_class ". But it is not...

Shouldn't the .find arguments be of the same type as the elements of set itself? This is what the documentation says ...

+6
source share
1 answer

This works because int implicitly converted to your class. Any constructor that is not marked explicit and can be called with just one argument that is not of the type of the class itself defines an implicit conversion. Effectively this means that whenever an object of type class is expected, you can also use int , and it will be automatically converted.

+12
source

Source: https://habr.com/ru/post/909557/


All Articles