Indexing Operators
Learn to overload indexing operators for structs.
We'll cover the following
Use of indexing operators
opIndex
, opIndexAssign
, opIndexUnary
, opIndexOpAssign
, and opDollar
make it possible to use indexing operators on user-defined types similar to arrays as in object[index]
.
Unlike arrays, these operators support multi-dimensional indexing as well. Multiple index values are specified as a comma-separated list inside the square brackets (e.g., object[index0, index1]
). In the following examples, we will use these operators only with a single dimension and cover their multidimensional uses in the more templates chapter.
Here, e
is a variable of type int
.
opIndex
is for element access. The index
that is specified inside the brackets becomes the parameter of the operator function:
e = deque[3]; // the element at index 3
e = deque.opIndex(3); // the equivalent of the above
opIndexAssign
is for assigning a value to an element. The first parameter is the value that is being assigned, and the second parameter is the index of the element:
deque[5] = 55; // assign 55 to the element at index 5
deque.opIndexAssign(55, 5); // the equivalent of the above
opIndexUnary
is similar to opUnary
. The difference is that the operation is applied to the element at the specified index:
++deque[4]; // increment the element at index 4
deque.opIndexUnary!"++"(4); // the equivalent of the above
opIndexOpAssign
is similar to opOpAssign
. The difference is that the operation is applied to an element:
deque[6] += 66; // add 66 to the element at index 6
deque.opIndexOpAssign!"+"(66, 6);// the equivalent of the above
opDollar
defines the $
character that is used during indexing and slicing. It is for returning the number of elements in the container:
e = deque[$ - 1]; // the last element
e = deque[deque.opDollar() - 1]; // the equivalent of the above
Indexing operators example
Double-ended queue is a data structure that is similar to arrays, but it also provides efficient insertion at the head of the collection.
In contrast, inserting at the head of an array is a relatively slow operation as it requires moving the existing elements to a newly created array.
One way of implementing a double-ended queue is to use two arrays in the background but to use the first one in reverse. The element that is conceptually inserted at the head of the queue is actually appended to the head array. As a result, this operation is as efficient as appending the element to the end.
The following struct implements a double-ended queue that overloads the operators that we have seen in this section. The deque
variable in the following examples is an object of struct DoubleEndedQueue
:
Get hands-on with 1400+ tech skills courses.