There is a problem with your approach even if you could define a lambda the way you want to. Take a look at the multiset
declaration:
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class multiset;
Notice how each template parameter is a type (using the class
keyword). Now look at how you tried to define your list:
using list = std::multiset<int, compare>;
^ ^
type value
The first parameter is good, but the second is a mismatch. The Compare
parameter needs to be a type, not an object. One general way to resolve this sort of situation is to replace compare
with decltype(compare)
, but that seems to be not what you want (plus it is problematic for lambda types). You seem to want a default constructed list
to use compare
instead of merely a default constructed object of the same type.
So what you need is a class whose default constructed object implements operator()
in a way that gives the order you want. Since we're dealing with int
, the standard library has some ready-made types for this purpose, namely std::less
and std::greater
.
using list = std::multiset<int, std::greater<int>>;
However, I cannot overload operator(), std::less, std::greater.
Hmm... this suggests that the example code may have been over-simplified, as an overload is not called for. OK, let's suppose the list is of some type that's harder to deal with, say:
class I { /* Internals not important for this example. */ };
using list = std::multiset<I, ???>;
If you are allowed to modify I
, then the simplest approach might be to define operator>
(or operator<
) for objects of type I
. Since std::greater
(or std::less
) uses this operator, you get the desired order from the standard template without overloading it.
If you are not allowed to modify I
, then I think you're left with writing your own function object, as this is one situation where a lambda is inadequate. Fortunately, classes implementing function objects are easy to write; lambdas have superseded them in other situations mostly because the lambda syntax tends to be more convenient.
struct CompareI {
bool operator() (const I & lhs, const I & rhs) const { return /* fill this in */; }
};
using list = std::multiset<I, CompareI>;
While this defines an operator()
, it is not an overload. So it should satisfy the requirements given to you.