Consider following comparison function:
bool compare(std::shared_ptr &lhs, std::shared_ptr &rhs){
return lhs->val
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;
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.
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.