为什么STL <set>重载运算符&lt;函数必须是const函数?</set>

时间:2014-09-28 08:45:32

标签: c++ stl set operator-overloading

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”?

2 个答案:

答案 0 :(得分:4)

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

如果允许比较函数修改值,则永远不能使用它,因为集合中的值总是const。

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

答案 1 :(得分:1)

您无需这样做。通常建议这样做,因为在比较它们的过程中不应修改对象。 set<Test>通过将const引用传递给operator<来使其成为一种要求。