найти по ключу в std :: set - PullRequest
1 голос
/ 04 мая 2020

Я борюсь с std::set, который должен поддерживать пользовательские операции сравнения. Моя цель состояла бы в том, чтобы иметь возможность вызывать find только с ключевым аргументом, без предварительного создания объекта заданного типа. Примерно так:

#include <set>
#include <cstdint>
#include <vector>

class TestItem {
  public:
    std::uint64_t id;          // key
    std::vector<double> areas; // some other data
};

struct TestItemCompare {
    bool operator()(const std::uint64_t& lhs, const std::uint64_t& rhs) {
        return lhs < rhs;
    }
    bool operator()(const std::uint64_t& lhs, const TestItem& rhs) {
        return lhs < rhs.id;
    }
    bool operator()(const TestItem& lhs, const std::uint64_t& rhs) {
        return lhs.id < rhs;
    }
    bool operator()(const TestItem& lhs, const TestItem& rhs) {
        return lhs.id < rhs.id;
    }
};

int main() {
    std::set<TestItem, TestItemCompare> store;
    std::uint64_t id = 0;
    TestItem t;
    t.id = 0;

    auto it1 = store.find(t);    // compiles
    auto it2 = store.find(id);   // fails to compile

    return 0;
}

Я думал, что это возможно ...

1 Ответ

5 голосов
/ 04 мая 2020

Это возможно. Но ваш компаратор должен быть прозрачным. И функции-члены в функторе должны быть const

struct TestItemCompare {
    using is_transparent = int; // actually any alias will do, void, custom type
    bool operator()(const std::uint64_t& lhs, const std::uint64_t& rhs) const {
        return lhs < rhs;
    }
    bool operator()(const std::uint64_t& lhs, const TestItem& rhs) const {
        return lhs < rhs.id;
    }
    bool operator()(const TestItem& lhs, const std::uint64_t& rhs) const {
        return lhs.id < rhs;
    }
    bool operator()(const TestItem& lhs, const TestItem& rhs) const {
        return lhs.id < rhs.id;
    }
};
...