How to Overload Subscript Operator in C++

Jinku Hu Feb 02, 2024
How to Overload Subscript Operator in C++

This article will demonstrate how to overload subscript/index operator in C++.

Overload Subscript Operator Using the operator[] Notation in C++

Operator overloading is a powerful feature of the C++ language. It gives the programmer the facilities to redefine the meaning of existing operators for any user-defined classes. Essentially, overloaded operators are functions and are defined as such, except that they have special names. The names must start with the prefix operator followed by the operator symbol that’s being overloaded.

Generally, operator overload functions have the same number of parameters as the given operator’s operands. So, our subscript operator overload will accept two parameters. The following example code demonstrates a MyClass class implementation which has the operator[] member function that conducts an element access operation on the internal vector structure and returns the reference to the element. MyClass is basically the wrapper class around the std::vector container and provides several member functions for the sake of demonstration.

Notice that the operator[] member function has one parameter as the usual subscript operator. Mind though, when the operator function is declared as a member function, it has the first parameter bound to implicit this pointer. Thus, we can have one less parameter than the operands for operator overloads declared as member functions.

#include <iostream>
#include <string>
#include <vector>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

template <typename T>
class MyClass {
 public:
  MyClass() = default;
  explicit MyClass(const T &data) { vec.push_back(data); };
  MyClass(std::initializer_list<T> list) {
    vec.insert(vec.end(), list.begin(), list.end());
  };

  void push_back(const T &data) { vec.push_back(data); };

  void pop_back() { vec.pop_back(); };

  size_t size() { return vec.size(); };

  T &operator[](size_t pos) { return vec.at(pos); };

  const T &operator[](size_t pos) const { return vec.at(pos); };

 private:
  vector<T> vec;
  string name;
};

int main() {
  MyClass<string> m1 = {"top", "mop", "gop", "sop"};

  for (size_t i = 0; i < m1.size(); ++i) {
    cout << m1[i] << endl;
  }

  cout << "/ ------------------- /" << endl;

  m1.pop_back();
  m1.pop_back();

  for (size_t i = 0; i < m1.size(); ++i) {
    cout << m1[i] << endl;
  }

  return EXIT_SUCCESS;
}

Output:

top
mop
gop
sop
/ ------------------- /
top
mop

Note that some operators must be overloaded as the member function, and one of them is a subscript operator. The operator[] function is recommended to have a similar meaning as the built-in operator, which retrieves the element by the given position. The subscript overload should return a reference to be used on both sides of the assignment. It’s also important to define two versions of the operator[] function, one for non-const objects and the other for const objects, since we don’t want the returned reference to be assignable when the object itself is const qualified.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Operator