Overloading Subscript or array index operator [] in C++

Last Updated : 18 Jun, 2026

The subscript operator ([]) is used to access elements of arrays and array-like objects. In C++, it can be overloaded for user-defined classes to customize how elements are accessed and modified.

  • Enables custom classes to behave like arrays.
  • Commonly used while implementing custom containers, matrices, and wrapper classes.
CPP
char name[] = "Ramswarup";

cout << name[5] << endl;
cout << 5[name] << endl;

Output
a
a

Explanation: Both expressions are equivalent because a[b] is internally treated as *(a + b).

Syntax

return_type& operator[](int index);

  • Must be implemented as a member function.
  • Usually returns a reference so elements can be modified.
  • Accepts the index value as its parameter.

Positive and Negative Subscripts

Array elements are normally accessed using indices from 0 to size - 1. Although pointer arithmetic allows negative indexing relative to a valid pointer, accessing memory outside the array bounds results in undefined behavior.

CPP
#include <iostream>
using namespace std;

// Driver Method
int main()
{
    int intArray[1024];
    for (int i = 0, j = 0; i < 1024; i++) {
        intArray[i] = j++;
    }

    // 512
    cout << intArray[512] << endl;

    // 257
    cout << 257 [intArray] << endl;

    // pointer to the middle of the array
    int* midArray = &intArray[512];

    // 256
    cout << midArray[-256] << endl;

    // unpredictable, may crash
    cout << intArray[-256] << endl;
}

Output
512
257
256
60426920

Overloading the [] Operator

The subscript operator can be overloaded to allow objects of a user-defined class to be accessed using array syntax.

Example: Custom Array Class

CPP
#include <cstdlib>
#include <iostream>

using namespace std;

// A class to represent an integer array
class Array {
private:
    int* ptr;
    int size;

public:
    Array(int*, int);

    // Overloading [] operator to access elements in array
    // style
    int& operator[](int);

    // Utility function to print contents
    void print() const;
};

// Implementation of [] operator. This function must return
// a reference as array element can be put on left side
int& Array::operator[](int index)
{
    if (index >= size) {
        cout << "Array index out of bound, exiting";
        exit(0);
    }
    return ptr[index];
}

// constructor for array class
Array::Array(int* p = NULL, int s = 0)
{
    size = s;
    ptr = NULL;
    if (s != 0) {
        ptr = new int[s];
        for (int i = 0; i < s; i++)
            ptr[i] = p[i];
    }
}

void Array::print() const
{
    for (int i = 0; i < size; i++)
        cout << ptr[i] << " ";
    cout << endl;
}

// Driver program to test above methods
int main()
{
    int a[] = { 1, 2, 4, 5 };
    Array arr1(a, 4);
    arr1[2] = 6;
    arr1.print();
    arr1[8] = 6;
    return 0;
}

Output
1 2 6 5 
Array index out of bound, exiting

Explanation: The overloaded operator[] allows objects of Array class to be accessed using array syntax. It also performs bounds checking before returning the requested element.

Returning a Reference from operator[]

When overloading the subscript operator, it is recommended to return a reference instead of a value. Returning a reference allows elements to be modified directly using the subscript operator.

  • Enables assignments such as arr[2] = 10.
  • Avoids creating unnecessary copies of elements.
  • Makes the overloaded operator behave like the built-in array subscript operator.

Const-Correctness in operator[]

To support const objects, a separate const overload of operator[] should be provided. This allows read-only access while preventing accidental modification of elements.

  • The non-const version allows both reading and modifying elements.
  • The const version provides read-only access to elements.
C++
#include <cstdlib>
#include <iostream>
using namespace std;

// A class to represent an integer array
class Array {
private:
    int* ptr;
    int size;

public:
    Array(int*, int);

    // Overloading [] operator to access elements in array
    // style
    int& operator[](int);
    const int& operator[](int) const;

    // Utility function to print contents
    void print() const;
};

// Implementation of non-const [] operator. This function
// must return a reference as array element can be put on
// the left side
int& Array::operator[](int index)
{
    if (index >= size) {
        cout << "Array index out of bound, exiting";
        exit(0);
    }
    return ptr[index];
}

// Implementation of const [] operator. This function allows
// read-only access
const int& Array::operator[](int index) const
{
    if (index >= size) {
        cout << "Array index out of bound, exiting";
        exit(0);
    }
    return ptr[index];
}

// Constructor for array class
Array::Array(int* p = NULL, int s = 0)
    : size(s)
    , ptr(NULL)
{
    if (s != 0) {
        ptr = new int[s];
        for (int i = 0; i < s; i++)
            ptr[i] = p[i];
    }
}

// Utility function to print contents
void Array::print() const
{
    for (int i = 0; i < size; i++)
        cout << ptr[i] << " ";
    cout << endl;
}

// Driver program to test above methods
int main()
{
    int a[] = { 1, 2, 4, 5 };
    Array arr1(a, 4);
    arr1[2] = 6;
    arr1.print();

    // Uncommenting the next line will cause an error
    // because the index is out of bounds arr1[8] = 6;

    const Array arr2(a, 4);
    cout << arr2[2] << endl;
    // Uncommenting the next line will cause an error
    // because arr2 is const and cannot modify its elements
    // arr2[2] = 7;

    return 0;
}

Output
1 2 6 5 
4

Multidimensional Subscript Operator in C++23

Starting from C++23, operator[] can accept multiple indices for user-defined classes, making multidimensional indexing more intuitive.

  • Allows passing multiple indices inside a single pair of square brackets (e.g., matrix[2, 3]).
  • Works only with user-defined classes and is not supported for C-style arrays or standard containers.
  • Introduced as part of the C++23 proposal P2128 to improve the usability of operator[].
  • Eliminates the need for proxy classes or using operator() for multidimensional indexing, resulting in cleaner and more readable code.
Comment