For your first example:
multiset<int, greater<int> > ms1;
This says that ms1
is a std::multiset
, storing int
, and using a comparison functor of the type std::greater<int>
. You've left out constructor arguments, so the instance of the functor is a default constructed one, exactly as if you had passed std::greater<int>{}
, like this:
multiset<int, greater<int> > ms1(greater<int>{});
In your second example:
multiset<int> ms2(greater<int>());
This one is a bit tricky. There are 2 problems here. The first one relates to what is called "The Most Vexing Parse". It has been answered many times, so I will simply link to one of those answers. Most vexing parse: why doesn't A a(()); work?
So let's assume you understand that, and modify your code accordingly to this:
multiset<int> ms2(greater<int>{});
// or this
multiset<int> ms2((greater<int>()));
In this case, you've left out the type of the comparison functor, and gone with the default. The default is std::less<int>
. So the above line is equivalent to this:
multiset<int, std::less<int> > ms2(greater<int>{});
What that says is that ms2
is a std::multiset
, storing int
, and using a comparison functor of type std::less<int>
. You are then passing an instance of std::greater<int>
to the constructor. std::less<int>
and std::greater<int>
are different types. You can't pass an instance of one to a function that is expecting an instance of the other.