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.
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.
#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
#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.
#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.