为什么std :: set<> :: find返回一个const?

时间:2012-02-26 17:01:59

标签: c++ stl set const

  

可能重复:
  C++ STL set update is tedious: I can't change an element in place

我想使用std::set<>来计算某个值的出现次数并同时对对象进行排序。为此我创建了一个类RadiusCounter

class RadiusCounter
{
public:
    RadiusCounter(const ullong& ir) : r(ir) { counter = 1ULL; }
    void inc() { ++counter; }
    ullong get() const { return counter;}
    ullong getR() const { return r;}
    virtual ~RadiusCounter();
protected:
private:
    ullong r;
    ullong counter;
};

(析构函数不做任何操作)和比较运算符:

const inline bool operator==(const RadiusCounter& a, const RadiusCounter& b) {return  a.getR() == b.getR();}
const inline bool operator< (const RadiusCounter& a, const RadiusCounter& b) {return a.getR() < b.getR();}
const inline bool operator> (const RadiusCounter& a, const RadiusCounter& b) {return a.getR() > b.getR();}
const inline bool operator!=(const RadiusCounter& a, const RadiusCounter& b) {return a.getR() != b.getR();}
const inline bool operator<=(const RadiusCounter& a, const RadiusCounter& b) {return a.getR() <= b.getR();}
const inline bool operator>=(const RadiusCounter& a, const RadiusCounter& b) {return a.getR() >= b.getR();}

现在我想这样使用它:

set<RadiusCounter> theRadii;
....
ullong r = getSomeValue();

RadiusCounter ctr(r);
set<RadiusCounter>::iterator itr = theRadii.find(ctr);

// new value -> insert
if (itr == theRadii.end()) theRadii.insert(ctr);

// existing value -> increase counter
else itr->inc();

但是现在编译器在调用itr->inc()

的行中抱怨
error: passing 'const RadiusCounter' as 'this' argument of 'void RadiusCounter::inc()' discards qualifiers

为什么*itr中的实例是const?

3 个答案:

答案 0 :(得分:9)

因为您无法修改std::set中的元素。如果可以,它将允许它破坏严格弱排序不变量的可能性,导致未定义的行为。

如果要修改元素,则应擦除元素,然后插入新元素。

答案 1 :(得分:3)

另外,似乎你只想要

typedef int Radius;
typedef int Counter
std::map<Radius, Conunter>theRadii;

...

theRadii[getSomeValue()]++;

答案 2 :(得分:1)

碰巧我几小时前已经回答了这个问题:https://stackoverflow.com/a/9452445/766580。基本上,您无法更改set元素的值,因为set无法知道您更改了什么。如果要执行此操作,则需要删除并重新插入修改后的值。