ProgrammingC++ Middle Developer

What is operator[] in C++? How to properly overload this operator for custom containers?

Pass interviews with Hintsage AI assistant

Answer.

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:

  • Always implement both the const and non-const versions of the operator for correct operation with const objects
  • Does not perform out-of-bounds checks (unlike .at() in standard containers)
  • It is important to choose the return type (reference, pointer, value) intentionally

Tricky questions.

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.

Common mistakes and anti-patterns

  • Not implementing the const version of the operator (which prevents accessing elements through const references)
  • Returning a value instead of a reference, breaking the assignment semantics
  • Leaving uninitialized elements in the container

Real-life example

Negative case

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:

  • Compiles as long as you use only non-const objects

Cons:

  • Expected C++ semantics are violated
  • Does not support const-correctness, standard algorithms cannot be used

Positive case

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:

  • The container behaves "as expected"
  • All modes are supported (const, non-const, read, write)

Cons:

  • Using operator[] still allows for out-of-bounds errors
  • Slightly increases class complexity