Using Templates in Multi-Dimensional Operator Overloading

Learn how to use templates in multi-dimensional operator overloading.

We'll cover the following

Multi- dimensional operator overloading

In the operator overloading chapter, you saw that opDollar, opIndex, and opSlice are for element indexing and slicing. When overloaded for single-dimensional collections, these operators have the following responsibilities:

  • opDollar: Returns the number of elements of the collection

  • opSlice: Returns an object that represents some or all of the elements of the collection

  • opIndex: Provides access to an element

These operator functions have templated versions as well, which have different responsibilities from the non-templated ones above. Note that in multi- dimensional operator overloading opIndex assumes the responsibility of opSlice.

  • opDollar template: Returns the length of a specific dimension of the collection. The dimension is determined by the template parameter:
    size_t opDollar(size_t dimension)() const 
    {
        // ...
    }
    
  • opSlice template: Returns the range information that specifies the range of elements (e.g., the begin and end values in array[begin..end]). The information can be returned as Tuple!(size_t, size_t) or an equivalent type. The dimension that the range specifies is determined by the template parameter:
    Tuple!(size_t, size_t) opSlice(size_t dimension)(size_t begin,size_t end)
        return tuple(begin, end); 
    }
    
  • opIndex template: Returns a range object that represents a part of the collection. The range of elements are determined by the template parameters:
    Range opIndex(A...)(A arguments) {
        // ...
    }
    

opIndexAssign and opIndexOpAssign also have templated versions, which operate on a range of elements of the collection. The user-defined types that define these operators can be used with the multi-dimensional indexing and slicing syntaxes:

Get hands-on with 1000+ tech skills courses.