The index access operator operator[] is an overloaded operator in C++ that provides indexing syntax for objects of custom containers (e.g., like arrays).
Background:
In C, and later in C++, the operator [] allowed quick and convenient access to array elements by index. However, with the growing popularity of container classes, there arose a need to apply the same syntax to user-defined data types.
Problem:
Properly designing index access operators is associated with issues of constness, out-of-bounds safety, choice of return value, and guarantees of reference or pointer validity.
Solution:
In C++, you can overload operator[] for classes to allow accessing elements by index and implement "array-like" behavior for them. Both versions of the operator need to be implemented—regular (for non-const objects) and const (for const objects).
Example code:
class MyArray { int data[10]; public: int& operator[](size_t index) { return data[index]; } const int& operator[](size_t index) const { return data[index]; } }; MyArray arr; arr[3] = 42; // OK const MyArray& const_arr = arr; int val = const_arr[3]; // OK
Key features:
.at() in standard containers)Is it mandatory to return a reference from operator[]?
No — but if you return a value, the syntax arr[i] = x; will not work (you will be copying instead of assigning). To maintain the expected container semantics, it is usually advisable to return a reference. If you return a value, you cannot assign to the element:
int operator[](size_t idx); // arr[2] = 10; will not compile
Should operator[] check boundaries?
The standard does not require this. The classic operator[] (like in std::vector) does NOT perform such checks. For boundary checks, the standard containers introduce a separate method .at(), which throws an exception when accessing out of range.
Can operator[] be a const method?
No — if you return a non-const reference. However, you need to overload operator[] for both const and non-const objects so that the container works intuitively and safely.
A young developer implemented only the non-const version of operator[], returning by value. As a result, the container could not be accessed through a const reference, and any assignment attempts worked oddly — values were not preserved.
Pros:
Cons:
In the container MyArray, both versions of operator[] are implemented, returning references correctly. A method at() with boundary checks has been added when necessary.
Pros:
Cons: