The type expected by multiset
second parameter is a Predicate. That is the type of an object c
such that c(lhs, rhs)
returns something convertible to bool
.
The type of compare
and decltype(compare)
is bool(shared_ptr<int>, shared_ptr<int>)
, a function type. There can't be values of function type, but there can be values of pointers and references to function types. That's why you need the *
there. (Actually, there are values of function types and are those things that you declare as functions, but those cannot be created, copied, nor pretty much anything besides calling them and getting their address.) Summing up:
decltype(compare)* ==> bool (*)(shared_ptr<int>, shared_ptr<int>)
which is a pointer to a function taking two shared_ptr<int>
s by value and returning a bool
. Then, in the multiset
constructor, you give it a value of that type:
items{ compare }; // value
or more specifically, a value of a function type that will decay to a function pointer type. So let's make that explicit:
items{ &compare }; // pointer to function compare
If you didn't give it anything, then it would be a null pointer, and when trying to call it to do the comparison your application would crash.
In summary, you chose a hell of a complicated case to go through (and I have skipped a few things I should mention). This is a simpler approach:
struct shared_ptr_compare
{
bool operator()(std::shared_ptr<int> const& lhs, std::shared_ptr<int> const& rhs) const
{ return /*...*/; }
};
multiset<shared_ptr<int>, shared_ptr_compare> item; // no need to initialize
// shared_ptr_compare with anything, a default value will do just fine
Note: I dropped the top-level const
modifier as it has no effect on a function parameter, it only signals the function body that the values cannot be changed. So it does have meaning, but complicates explaining types.
Note 2: You should take those parameters as shared_ptr<int> const&
(same thing as const shared_ptr<int>&
), since you do not actually need a copy and those copies have to keep a reference counter which is an operation that has to be synchronized among threads.