阅读错误信息的方法如下:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_tree.h:1141: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = node, _Val = std::pair<const node, bool>, _KeyOfValue = std::_Select1st<std::pair<const node, bool> >, _Compare = std::less<node>, _Alloc = std::allocator<std::pair<const node, bool> >]’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_map.h:469: instantiated from ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = node, _Tp = bool, _Compare = std::less<node>, _Alloc = std::allocator<std::pair<const node, bool> >]’
prog.cpp:15: instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’
首先,我们忽略了大部分“instantiated from”行,因为它们只是在谈论模板是如何扩展的。重要的是最后一个,指的是我们的源代码,因为它告诉我们错误是在哪里触发的。当然,无论如何我们都知道这一点,所以我们也将跳过它。我们还将忽略相关库头的路径,因为我们并不真正关心编译器如何存储其内容。
stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’:
stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’
所以...我们的代码间接调用‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’,或者如果我们确实进行了替换,则‘bool std::less<node>::operator()(const node&, const node&) const’。这是一个问题,因为有no match for ‘operator<’ in ‘__x < __y’。
__x 和__y 是std::less 实现中的变量(你应该可以猜到这么多)。从名称中,我们可以猜测(如果我们研究过标准库,我们就会知道)std::less 是一个模板函数,它比较两个相同类型的东西,并返回第一个是否小于第二个。
它是如何做到的?当然,通过使用operator<。所以这就是我们需要做的来解决这个问题:它说operator< 不存在用于比较的内容,所以我们必须提供它。比较的是什么? nodes,当然。所以我们为我们的班级定义了operator<。
为什么要这样做?这样我们就可以编写接受比较操作作为参数的函数(模板参数或运行时参数 - 但前者更常见),并传递std::less。这就是std::less存在的原因:它将比较事物的行为变成了一个函数,而实际的函数更有用一些。
这有什么关系?因为,就像其他人所说的那样, std::map 实际上将 std::less 作为参数传递。它实际上是用于比较元素的std::map 模板的默认参数。毕竟,地图接口的一部分是每个键都是唯一的。如果您无法比较它们,您将如何检查键的唯一性?当然,从技术上讲,您只需要比较它们的平等性就可以了。但事实证明,能够对键进行排序使得创建更高效的数据结构成为可能。 (如果你真的在大学里学过编程和 CS 的课程,你就会知道这一点。)
为什么int 没有问题?你现在应该可以猜到了:operator< 已经自然地适用于ints。但是您必须告诉 C++ 如何为任何用户类型执行此操作,因为您可能有其他想法。