是否不可能将 STL 映射与结构体作为键一起使用?
我有以下代码:
struct Node
{
int a;
int b;
};
Node node;
node.a = 2;
node.b = 3;
map<int, int> aa;
aa[1]=1; // OK.
map<Node, int> bb;
bb[node]=1; // Compile error.
当我尝试将结构 Node
的实例映射到 int
时,出现编译错误。为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果您确实不需要按键对数据进行排序,则可以使用新的 unordered_map:
您需要一个最新的编译器才能使其工作。
更新
正如 Neil 指出的,如果您想要带有 Node 键的 unordered_map,则需要一个专门的哈希函数。
然后映射变成:
另外,正如 sellibitze 所说,在哈希冲突的情况下需要一个运算符 == 来比较键:
所以我想 std::map 毕竟更容易使用。
If you don't really need to have your data sorted by key, you can use the new unordered_map:
You'll need a recent compiler for this to work.
UPDATE
As Neil points out you need an specialized hash function if you want an unordered_map with
Node
keys.And then the map becomes:
Also, as sellibitze says, an operator== is needed to compare keys in case of hash collision:
So I guess that std::map is much easier to use after all.
您能否发布编译器错误 - 他们的目的是告诉您,出了什么问题。
我猜您会发生错误,因为
Node
没有实现地图所需的比较运算符来识别其元素。Could you please post the compiler error - They're intended to tell you, what's wrong.
I guess your error occurs since
Node
doesn't implement a comparison operator which is required by the map in order to identify it's elements.由于 std::map 按其键排序,因此您必须定义如何比较两个
Node
对象。自 C++11 起,您还可以使用 lambda 表达式 而不是定义比较运算符。因此,您可以将代码保持简短,如下所示:输出:
请根据您的需要替换 lambda 表达式的主体。
Ideone 上的代码
As a std::map is sorted by its keys, you have to define how to compare two
Node
objects. Since C++11 you can also use a lambda expression instead of defining a comparison operator. As a result, you can keep your code as short as follows:Output:
Please replace the body of the lambda expression according to your needs.
Code on Ideone
对于可用作映射中的键的事物,您必须能够使用
operator<()
对其进行比较。您需要将这样的运算符添加到节点类中:当然,真正的运算符的作用取决于比较对您的结构的实际含义。
For a thing to be usable as a key in a map, you have to be able to compare it using
operator<()
. You need to add such an operator to your node class:Of course, what the real operator does depends on what comparison actually means for your struct.
您必须告诉 std::map 如何比较 Node 对象。默认情况下,它尝试使用小于运算符来执行此操作。但是您没有为 Node 提供任何小于运算符。最简单的解决方案是提供一个。
自由函数示例:
请注意,对于任何带有
!(x 和
!(y 的节点对象 x,y 对,映射将考虑 x 和y 相等(相同的键)。
You have to tell std::map how to compare the Node objects. By default it tries to do so by using the less than operator. But you didn't provide any less than operator for Node. The easiest solution would be to supply one.
Free function example:
Note that, for any pair of node objects x,y with
!(x<y)
and!(y<x)
the map will regard x and y as equal (same key).您需要定义小于运算符来启用您的节点类型的比较:
在这里您可以检查LessThan Comparable 表示用户定义类型。
替代解决方案是基于 std::binary_function。从设计的角度来看,此选项具有优势,因为比较与
Node
类有效地解耦。这使得可以定义专门用于不同比较条件(函子)的映射。因此,您可以定义更多的比较,而不仅仅是
NodeLessThan
,例如使用不同的条件或仅通过Node::a
进行比较,另一个比较两个组件Node:: a
和Node::b
。然后,定义不同类型的映射:这种解耦侵入性较小(根本不接触 Node 类),并且有利于实现更具可扩展性的解决方案。
You need to define less-than operator to enable comparisons for your Node type:
Here you may check what LessThan Comparable mean for a user-defined type.
Alternative solution is to define a functor based on std::binary_function. From design point of view, this option has advantages because comparison is effectively decoupled from the
Node
class. This makes it possible to define maps specialised with different comparison conditions (functors).So, you can define more comparisons than just
NodeLessThan
, for example using different conditions or one comparing only byNode::a
another comparing both components,Node::a
andNode::b
. Then, defined different types of maps:Such decoupling is less intrusive (does not touch Node class at all) and is beneficial to achieve more extensible solution.