Reputation: 2018
Why the code below does not compile?
#include <set>
struct FatKey { int x; int data[1000]; };
struct LightKey { int x; };
struct Compare
{
bool operator() (const FatKey& fk, const LightKey& lk) const { return fk.x < lk.x; }
bool operator() (const LightKey& lk, const FatKey& fk) const { return lk.x < fk.x; }
bool operator() (const FatKey& fk1, const FatKey& fk2) const { return fk1.x < fk2.x; }
};
int main()
{
// transparent comparison demo
std::multiset<FatKey, Compare> example2 = { {1, {} }, {2, {} }, {3, {} }, {4, {} } };
LightKey lk = {2};
auto search2 = example2.find(lk);
if (search2 != example2.end()) {
std::cout << "Found " << search2->x << '\n';
} else {
std::cout << "Not found\n";
}
}
What is wrong with the comparer?
It compiles if I replace the comparer with
bool operator<(const FatKey& fk, const LightKey& lk) { return fk.x < lk.x; }
bool operator<(const LightKey& lk, const FatKey& fk) { return lk.x < fk.x; }
bool operator<(const FatKey& fk1, const FatKey& fk2) { return fk1.x < fk2.x; }
and define multiset as
std::multiset<FatKey, std::less<>>
what is the difference?
Upvotes: 1
Views: 50
Reputation: 36379
If you want to use the overloads of find
which take an equivalent type and you are using a custom comparator class that class must have a is_transparent
member type:
#include <set>
#include <iostream>
struct FatKey { int x; int data[1000]; };
struct LightKey { int x; };
struct Compare
{
bool operator() (const FatKey& fk, const LightKey& lk) const { return fk.x < lk.x; }
bool operator() (const LightKey& lk, const FatKey& fk) const { return lk.x < fk.x; }
bool operator() (const FatKey& fk1, const FatKey& fk2) const { return fk1.x < fk2.x; }
using is_transparent = void;
};
int main()
{
// transparent comparison demo
std::multiset<FatKey, Compare> example2 = { {1, {} }, {2, {} }, {3, {} }, {4, {} } };
LightKey lk = {2};
auto search2 = example2.find(lk);
if (search2 != example2.end()) {
std::cout << "Found " << search2->x << '\n';
} else {
std::cout << "Not found\n";
}
}
Upvotes: 3