Are there any advances in recent C that allows for differentiating between getting and setting values via the operator[]
of a class? (as Python does via __setitem__
and __getitem__
)
const T& operator[](unsigned int index) const;
T& operator[](unsigned int index);
I am wrapping an std::unordered_map
, and want to let my users access the data via the operator[]
, but also do some behind the scenes record-keeping to keep things aligned in my data structure.
Searching reveals a few answers, but they are all many years old, and I was wondering if C has added extra functionality in the meantime.
CodePudding user response:
Actually there is not such a getting operator[] and setting operator[]. There are just constant and non-constant [] operators.
When objects are large, returning by reference may save an object creation, and also gives an opportunity to change the element on that position, so it makes sense to define these operators to return by reference than by value. To make the operator available on constant objects too, you should mark the constant overload with const keyword. The idea has not been cahanged since old times.
BTW, the STL has sligtly deffernet approaches with regard the container type. For example if you call [] with an out of range index in a vector, it will throw, but simillar call on a non-constant map will create a node with given key. To keep things a little bit more consistant, STL provides a function named at() which regardless of container class, checks the index and throws if it is out of range.
CodePudding user response:
Thanks all. Looks like no [] for this class.
Edit: you've convinced me. I'll have a go at implementing the solution in the first link.
Hopefully have a prototype ready tonight
CodePudding user response:
Assume your wrapper class implements set and get methods that perform the appropriate record keeping actions. The wrapper class can then also implement operator[]
to return a result object that will delegate to one of those methods depending on how the result is used.
This is in line with the first related question you identified (Operator[] C Get/Set).
A simple illustration is below. Note that a const
map would not be able to call set_item
anyway, so the const
overload of operator[]
calls get_item
directly.
class MapType {
...
struct Result {
MapType &map_;
KeyType key_;
Result (MapType &m, KeyType k) : map_(m), key_(k) {}
operator ValueType () const { return map_.get_item(key_); }
ValueType & operator = (ValueType rhs) {
return map_.set_item(key_, rhs);
}
};
...
ValueType get_item (KeyType key) const {
/* ... record keeping ... */
return map_.at(key);
}
ValueType & set_item (KeyType key, ValueType v) {
/* ... record keeping ... */
return map_[key] = v;
}
...
Result operator [] (KeyType key) { return Result(*this, key); }
ValueType operator [] (KeyType key) const {
return get_item(key);
}
...
};