【问题标题】:Why STL <set> the overload operator < function must be a const function?为什么 STL <set> 的重载运算符 < 函数必须是 const 函数?
【发布时间】:2014-09-28 08:45:32
【问题描述】:
class Test
{

public:

    int v;
    Test(int s)
    {
        v = s;
    }

    bool operator < (const Test & b) const
    {
        return v < b.v;
    }
};

int main()
{
    set <Test> t2;
    return 0;
}

当我重载 less 运算符时,为什么必须使用 const 函数?如果我不在那里写“const”,它就不会通过编译。所以我不知道为什么我必须在那里写“const”?

【问题讨论】:

  • 因为在比较的时候修改对象是没有意义的。

标签: c++ stl set operator-overloading


【解决方案1】:

原因是std::set 有点特殊:它存储的值不能改变(同样std::map 中的key_type)。这是因为set 是一个排序容器,它需要知道如何对值进行排序;更改集合中的值可能会导致程序损坏,因为set::set 无法知道值已更改,因此需要重新排序。

如果允许比较函数修改值,那么它将永远无法使用,因为集合中的值始终是 const。

顺便说一句,确实允许对值进行一些修改,特别是不影响排序顺序的修改。因此,如果您有一个具有自定义排序函数的集合,该函数按结构的一个字段排序,您可以修改该结构的其他字段,因为排序顺序将保持不变。但是std::set 无法理解哪些字段对排序顺序很重要,哪些不重要,所以整个值都是 const。您可以使用一些技巧,例如创建一些字段 mutable 来处理此问题,但在大多数情况下,这不是必需的(例如,您可以使用地图,并将可修改的部分放在 value_type 中)。

【讨论】:

    【解决方案2】:

    您不需要这样做。通常建议这样做,因为在比较对象的过程中不应修改对象。 set&lt;Test&gt; 通过将 const 引用传递给 operator&lt; 使其成为要求。

    【讨论】:

    • 如果你不这样做,一些实现会失败。
    • @juanchopanza:任何不允许非常量 operator&lt; 的实现都被破坏了。在 OP 的情况下,问题在于 set&lt;Test&gt; 试图将 const 引用传递给 operator&lt;,而不是 operator&lt; 本身。
    • 你有 C++ 标准参考吗?因为这意味着 gcc 4.8 和 4.9 已损坏(我确信我从 4.4 开始就已经看到了。)
    • 不,我没有,但我只是在 ideone 的 C++11 和 C++ 4.8.1 编译器 ideone.com/zgll93 ideone.com/etmMaz 以及 g++ 4.8 和 clang 6.0 下编译了一个非常量运算符vector 替换为 set 都会导致 OP 出现问题。
    • 集合为空。尝试在其中插入一个元素。
    猜你喜欢
    • 2015-06-24
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 2011-05-09
    • 2012-10-02
    • 2016-05-16
    相关资源
    最近更新 更多