我使用Node来保存协调器的(x, y),并尝试将4个节点插入映射中。下面的代码只打印2个节点,为什么?
{0,0}, 0
{1,2}, 3
如果我用
改变重载操作符'<'的代码bool operator<(const Node &ob) const
{
return x < ob.x or y < ob.y;
}
打印所有4个节点。我对操作员的理解<只影响键的顺序。>
#include <iostream>
#include <map>
template<typename T1, typename T2>
struct Node
{
T1 x;
T2 y;
Node(T1 x, T2 y): x(x), y(y) {}
bool operator<(const Node &ob) const
{
return x < ob.x and y < ob.y;
}
bool operator==(const Node &ob) const
{
return x == ob.x and y == ob.y;
}
};
int main()
{
std::map<Node<int, int>, int> map =
{
{{0, 0}, 0},
{{0, 1}, 1},
{{1, 0}, 2},
{{1, 2}, 3}
};
for (const auto &entry: map)
{
auto key = entry.first;
std::cout << "{" << key.x << "," << key.y << "}, " << entry.second << std::endl;
}
return 0;
}
#include <iostream>
#include <map>
template<typename T1, typename T2>
struct Node
{
T1 x;
T2 y;
Node(T1 x, T2 y): x(x), y(y) {}
bool operator<(const Node &ob) const
{
return x < ob.x and y < ob.y;
}
bool operator==(const Node &ob) const
{
return x == ob.x and y == ob.y;
}
};
int main()
{
std::map<Node<int, int>, int> map =
{
{{0, 0}, 0},
{{0, 1}, 1},
{{1, 0}, 2},
{{1, 2}, 3}
};
for (const auto &entry: map)
{
auto key = entry.first;
std::cout << "{" << key.x << "," << key.y << "}, " << entry.second << std::endl;
}
return 0;
}
std::map
认为两个元素相等,如果对于两个键a
和b
,比较器(在您的示例中是默认的std::less
)满足
!comp(a, b) && !comp(b, a)
让我们检查一下你的箱子:
首先插入键Node<int, int>(0, 0)
,然后是键Node<int, int>(0, 1)
。对于这些元素(以及您的operator<
),以下内容成立:
!std::less(Node<int, int>(0, 0), Node<int, int>(0, 1))
&& !std::less(Node<int, int>(0, 0), Node<int, int>(0, 1))
=>
!(Node<int, int>(0, 0) < Node<int, int>(0, 1))
&& !(Node<int, int>(0, 1) < Node<int, int>(0, 0))
=>
!(0 < 0 && 0 < 1) && !(0 < 0 && 1 < 0)
=>
!(false && true) && !(false && false)
=> !false && !false
=> true
所以两个节点被认为是相等的,没有插入发生。对于Node<int, int>(1, 0)
也是如此。
插入Node<int, int>(1, 2)
有效,因为
!(0 < 1 && 0 < 2) && !(1 < 0 && 2 < 0)
=>
!(true && true) && !(false && false)
=>
!true && !false
=>
false && true
=>
false
您可以通过使用另一个operator<
来解决这个问题,例如,正如评论中所说,通过使用std::tie
。