Reputation: 167
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??
Upvotes: 13
Views: 15206
Reputation: 22157
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.
Upvotes: 3
Reputation: 254431
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;
Upvotes: 16
Reputation: 55395
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.
Upvotes: 4
Reputation: 24576
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.
Upvotes: 1