Subscript operator overloading simulates multidimensional array detailing

  • 2020-04-02 01:34:38
  • OfStack

Recently in the writing of the game, the map class template as an example of how to simulate a multidimensional array!


    template <typename T_CELL_STYLE>
    class CMap
    {
    public:
        CMap(IN UINT row_num, IN UINT col_num, 
                  IN T_CELL_STYLE cell_style = static_cast<T_CELL_STYLE>(0));

        //The subscript operator overloads
        typename vector<T_CELL_STYLE>::iterator operator[](IN UINT x);
    public:
        const UINT m_ROW_NUM;    //Number of grid rows on the map
        const UINT m_COL_NUM;    //Number of grid columns on the map
    private:
        vector<T_CELL_STYLE> _m_map_data;    //Store map data

    }; 

We know that subscript operator overloads cannot be written as follows:
T_CELL_STYLE operator[][](IN UINT x, IN UINT y);

Although we cannot directly implement a pair of subscript operator overloads, we can simulate indirectly.

The idea is as follows: first, through a single subscript operation to return an lvalue with the ability of subscript operation, the lvalue to subscript operation, two subscript operation expressions to achieve double subscript operation. Here's an example:


    //Map size
    #define _MAP_ROW   30
    #define _MAP_COL    36
    //Map cell style
    typedef enum {
        _CELL_GROUND,
        _CELL_GRASS,
        _CELL_BRICK,
        _CELL_STEEL,
        _CELL_WATER
    } CELLSTYLE;

    CMap<CELLSTYLE> myMap(_MAP_ROW, _MAP_COL, _CELL_GROUND);
    //Gets the cell style for row 3 and column 5 of the map
    vector<T_CELL_STYLE>::iterator iter = myMap[3];
    CELLSTYLE aCell = iter[5];

We set the above two subscript operation expressions together, as follows:
CELLSTYLE aCell myMap [3] [5].

So you get a double index operation, which looks like you're manipulating a two-dimensional array. Okay, so let's see how we reload.


    template <typename T_CELL_STYLE>
    inline typename vector<T_CELL_STYLE>::iterator
    CMap<T_CELL_STYLE>::operator[](IN UINT x)
    {
        if (m_ROW_NUM <= x)
        { 
            overflow_error e("overflow - CMap<T_CELL_STYLE>::operator[]");
            throw(e);
        }
        return _m_map_data.begin() + x * m_COL_NUM;
    }

See, isn't that simple? The intermediate procedure borrows from a member of a class type that has the ability to subscript.


Related articles: