Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I don't understand why the following works (although I'm glad that it works!):

I can define an std::set of Objects with a custom comparator. This custom comparator works by comparing some member variable of the two Objects being compared. BUT then I can use set's .find(x) function with x being of the member variable type rather than an object itself, and it works!

Here is an extremely 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); 

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

I would have expected the above code to not compile, and for the compiler to yell at me that " 18 is not of type my_class ". But it doesn't...

Shouldn't arguments to .find be of same type as the elements of the set itself? That's what the documentation seems to say...

like image 200
cmo Avatar asked Feb 28 '12 15:02

cmo


1 Answers

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

like image 167
Björn Pollex Avatar answered Oct 13 '22 01:10

Björn Pollex