One legitimate use (in my opinion) is with std::set
iterators. They are always const
, in order to prevent changing the key used in the set. Changing the key would break the internal structure of the set and cause undefined behavior.
However, as long as the key doesn't change it's safe to change other data in the object.
Let's say you have an std::set
like this:
std::set<MyObject> some_set;
And a class like this:
class MyObject {
public:
MyObject(const std::string &key)
: key_(key) {}
bool operator<(const MyObject &other) const {
return key_ < other.key_;
}
private:
// ...
// <some other data>
// ...
const std::string key_;
};
In the above example, the key is already const, so even if you modify the object, you cannot break the internal structure of the set.
Normally you can only get a const
reference out of a set iterator:
const MyObject &object = *some_set_iterator;
But since the key is const
, it's safe to const_cast
the dereferenced iterator:
MyObject &object = const_cast<MyObject &>(*some_set_iterator);