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...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With