如何使用其他类型的键搜索std :: map [英] How can I search an std::map using a key of a different type
问题描述
如果我有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.
我意识到我可以通过为X
和Y
创建一个通用的基类或接口并使其成为映射键来做到这一点,但是还有其他方法吗?例如创建某种比较器对象?
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
实例,原则上我应该能够在我的地图中找到匹配的项目,前提是我可以得到一个id
和subId
对.但是我可以在不创建X
实例并复制id
和subId
的情况下做到这一点吗?
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屋!