重载运算符<使用const,但不要将其作为const插入到map中

时间:2010-10-17 02:11:17

标签: c++ operator-overloading const

我遇到了问题。我有一个像这样的重载运算符的类..

class Foo
{
        friend bool operator<(const Foo &a, const Foo &b);
        ...
};

bool operator<(const Foo &a, const Foo &b)
{
        return a.member < b.member;
}

然后在一个类中的函数中,它将一些Foos作为键保存在地图中......

void Bar::Update()
{
        for (FooItr itr = foos.begin(); itr != foos.end();) {
                FooItr test = itr++;
                if (!test->first.Check()) { // Check() is const
                        my_map.insert(*test);
                        foos.remove(test);
                }
        }

        for (MapItr itr = my_map.begin(); itr != my_map.end(); ++itr) {
                itr->first.Update(); // Update is not const
        }
}

我收到一条错误消息,如...

error: passing ‘const Foo’ as ‘this’ argument of ‘void Foo::Update()’ discards qualifiers

我相信原因是my_map.insert()正在插入const Foos,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:4)

map中的密钥始终为const,即使您没有这样说。这就是为了防止编程错误。

考虑如果Update更改member会发生什么 - 地图数据结构将基于原始排序,但现在member已更改,那顺序可能是错误的!地图将完全破坏 - 您将无法正确查找,插入或删除数据。


因此,解决此问题的一些方法是:

  • 使用不同的数据结构,如果对象“乱序”无关紧要,例如vector
  • 移动在其他位置更新的数据。有时它确实属于mapped_typemap的第二个模板参数)。有时,您可以定义新的struct来存储当前的mapped_type以及需要更改的数据。
  • 如果您正在更改不影响类型可观察状态的内容(如缓存),那么我可能会建议更改数据成员mutable并创建相关成员函数const,或者存储scoped_ptr中的可变数据。但是,名为Update的函数表明正在更新的数据是该类型的基础。