Consider following comparison function:
bool compare(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs){
return lhs->value < rhs->value;
}
Now idea is to initialize a multiset of type std::shared_ptr<myObject>
which orders elements with above function. So from book i read it should be done like this:
std::multiset<std::shared_ptr<myObject>, decltype(compare)*> myset{compare};
QUESTION:
My question is, in the declaration i understand a function pointer is passed to refer to compare function, but why are we initializing the set with {compare}
? What is its importance and why is it necessary to do so like this??
Because the set needs a comparison functor to work with. If you don't specify one, it will make a default-constructed one. In this case, since you're using a function-pointer type, the default-constructed one will be a null pointer, which can't be called; so instead, you have to provide the correct function pointer at run time.
A better approach might be to use a function class type (a.k.a. functor type); then the function call can be resolved at compile time, and a default-constructed object will do the right thing:
struct compare {
bool operator()(std::shared_ptr<myObject> &lhs,
std::shared_ptr<myObject> &rhs) const {
return lhs->value < rhs->value;
}
};
std::multiset<std::shared_ptr<myObject>, compare> myset;
decltype(compare)*
in the template parameter specifies the type of the comparator. It doesn't tell which function is to be used - whether is it compare
, foo
, bar
or something else. Hence the constructor parameter.
In order to access your elements, you need to provide function for strict weak ordering for your type.
std::multiset
have the following constructor:
explicit multiset (const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());
As you can see, you can do this by passing comp
function pointer (or function object) to the constructor.
The comparator passed to the template has to be the type of something that can be called with the function call operator. That would be either a class that has overloaded that operator, or the type of a lambda or a function pointer. In the cunstrutor of set, an instance of that type has to be passed. So decltype(compare)*
is the function pointer type, and &compare
is the function pointer.
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