Reputation: 1464
For associative containers in C++, like set, map etc, we need to provide the custom key comparator type as a template parameter as follows.
bool compareMyType(const MyType& a, const MyType& b);
set<MyType, decltype(compareMyType)*> my_set(compareMyType); // OK
set<MyType> my_set(compareMyType); // ERROR
Why is this required? Why can't the type of comparator function be deduced by the type of key?
Upvotes: 0
Views: 185
Reputation: 117298
Your question has been answered so this is just input to how you could work around the problem:
You could supply operator<
for your type to avoid having to supply a less functor for it every time you use it in a set
.
#include <iostream>
#include <set>
struct MyType {
int value;
};
// added operator<
bool operator<(const MyType& l, const MyType& r) {
return l.value < r.value;
}
int main() {
std::set<MyType> my_set = {{3}, {2}, {1}};
for(const MyType& m : my_set)
std::cout << ' ' << m.value;
std::cout << "\n";
}
Output:
1 2 3
If you want to use it with hash based containers (like unordered_set
), you can similarly add a std::hash<MyType>
class that will be used per default for your type.
Upvotes: 2
Reputation: 180585
Unlike functions, there is no partial deduction for class templates. If you provide template parameters to a class template then you need to provide all non defaulted parameters, and in set
's case you need to provide the comparison type since it defaults to std::less<T>
, which your function pointer is not convertible to.
There was a proposal to get partial deduction, but it was rejected and the only current thing being added to CTAD is that it will work through an alias.
Upvotes: 4
Reputation: 63124
Because the comparator is not necessarily a function (function pointer, even). In fact, the default value for that parameter is std::less<Key>
, which is a class template with an operator()
. But you could pass the type of anything that can be called with two MyType const&
and return a bool
, hence the need to specify what that thing actually is.
Upvotes: 1