Dmitriano
Dmitriano

Reputation: 2018

std::multiset comparer does not compile

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

Answers (1)

Alan Birtles
Alan Birtles

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

Related Questions