如何使用其他类型的键搜索std :: map [英] How can I search an std::map using a key of a different type

查看:107
本文介绍了如何使用其他类型的键搜索std :: map的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有std::map<X, Blah>,使用Y的实例在地图中查找匹配项的最佳方法是什么?

If I have std::map<X, Blah>, what is the best way of looking up a matching item in the map using an instance of Y?

假设Y中的信息足以唯一地找到X,但是出于性能原因,我不想通过复制Y值来创建X的实例.

Assume the information in Y is enough to uniquely find an X, but for performance reasons I don't want to create an instance of X by copying Y values.

我意识到我可以通过为XY创建一个通用的基类或接口并使其成为映射键来做到这一点,但是还有其他方法吗?例如创建某种比较器对象?

I realize I can do this by creating a common base class or interface for X and Y and making that the map key, but is there any other way? e.g. creating some sort of comparator object?

为清晰起见,以下是示例代码:

Here is the sample code for clarity:

class X
{
public:
    int id;
    int subId;
};

std::map<X, Details> detailsMap;

class Y
{
public:
    int getId();
    int getSubId();
    int someOtherUnrelatedThings1;
    int someOtherUnrelatedThings2;
};

现在,如果我有一个Y实例,原则上我应该能够在我的地图中找到匹配的项目,前提是我可以得到一个idsubId对.但是我可以在不创建X实例并复制idsubId的情况下做到这一点吗?

Now, if I have an instance of Y, in principle I should be able to find matching items in my map, given I can get an id and subId pair. But can I do it without creating an instance of X and copying over the id and subId?

推荐答案

使用C ++ 14,您可以使用异构查找.

With C++14 you can use heterogeneous lookup.

如果您想找到一个键,该键的键将等效std::map::find的参数进行比较,则应提供一个Comparator作为第三个模板参数,该参数应将Comparator::is_transparent表示为一种.它还应包含bool operator()将您的地图密钥与您想要的任何其他类型进行比较.

If you'd like to find an element with key that compares equivalent to the argument of std::map::find, you should provide a Comparator as a third template parameter which should have Comparator::is_transparent denoted as a type. It should also contain bool operator() comparing your map key with any other type you'd like.

除了有趣的描述之外,还有一个示例:

Funny description aside, here's an example:

struct X
{
    int id;
    int subid;
};

struct Details {};

struct Comparator
{
    using is_transparent = std::true_type;

    // standard comparison (between two instances of X)
    bool operator()(const X& lhs, const X& rhs) const { return lhs.id < rhs.id; }

    // comparison via id (compares X with integer)
    bool operator()(const X& lhs, int rhs) const { return lhs.id < rhs; }
    bool operator()(int lhs, const X& rhs) const { return lhs < rhs.id; }

    // Same thing with Y
    bool operator()(const X& lhs, const Y& rhs) const { return lhs.id < rhs.getId(); }
    bool operator()(const Y& lhs, const X& rhs) const { return lhs.getId() < rhs.id; }
};

int main()
{
    std::map<X, Details, Comparator> detailsMap = {
        { X{1, 2}, Details{} }, 
        { X{3, 4}, Details{} },
        { X{5, 6}, Details{} }
    };

    // it1 and it2 point to the same element.
    auto it1 = detailsMap.find(X{1, 2});
    auto it2 = detailsMap.find(1);

    std::cout << detailsMap.size() << std::endl;
    std::cout << std::boolalpha << (it1 == detailsMap.end()) << std::endl; // false
    std::cout << std::boolalpha << (it1 == it2) << std::endl; // true
}

但是请注意,直到版本 219888 为止,GCC才实施它.

Note however that GCC didin't implement it until revision 219888.

这篇关于如何使用其他类型的键搜索std :: map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆