Why would you need to overload the [] operator? I have never come across a practical scenario where this was necessary. Can somebody tell me a practical use case for this.
Err.. std::vector<t>
, std::basic_string<t>
, std::map<k, v>
, and std::deque<t>
?
I used this for a class representing a registry key, where operator[]
returned an object representing a registry value with the string between []s.
See also, the Spirit Parser Framework, which uses [] for semantic actions.
It is useful if you implement almost any type of container that provides random access (or at least some form of keyed access) to its elements (e.g., consider std::vector
).
If you write a class that inherits from another class that implements the [] operator, you might want to overwrite the [] operator, such as std::vector
or std::string
. If you don't do this, your class may not work as the user expects, as your class will implicitly inherit the parent's implementation of [].
Well, several STL containers give some examples - vector<>
overloads it to make it act like an array. map<>
for example provides the operator[]
overload to provide an 'associative array'.
While it is not strictly necessary, it is incredibly useful in making user-defined containers or strings behave like builtin arrays or C strings. This cuts down on verbosity a lot (for example, in Java, you would have to use x.getElementAt(i) while in C++ you can use x[i]; similarly, in Java you need x.compareTo(y)<0, while in C++ you can achieve the same thing using x < y). It is syntactic sugar... but it is very, very tasty.
Any indexable container can usefully define operator[]
to become usable in any template that uses []
-syntax indexing.
You don't need that syntax sugar if you're not doing generic programming -- it may look nice, but, cosmetics apart, you could always define specific named methods such as getAt
, setAt
, and the like, with similar and simpler-to-code functionality.
However, generic programming is at the core of modern C++... and it bears an eerie resemblance to "compile-time, type-safe duck typing" (I'm biased towards such peculiar terminology, of course, having had a part in shaping it -- cfr wikipedia;-).
Just as you should try to use, e.g., prefix-*
to mean "dereferencing" for all kinds of iterators and other pointer-like types (so they can be duck-typingly substituted for pointers in a template!), so similarly you should strive to define operator[]
in container types where it makes sense, just so they can be duck-typingly substituted for arrays in appropriate templates.