Search code examples
c++templatesmultidimensional-arraynon-type

Template non-type parameters and allocating array memory


There is an example class in a book I am reading used throughout to explain concepts:

class Gameboard{
public:
    Gameboard(int inWidth, int inHeight);
    Gameboard(const Spreadsheet& src);
    Gameboard& operator=(const Spreadsheet& rhs);

private:
    GamePiece** mCells;
    size_t width;
    size_t height;
};

they then introduce templates and introduce an updated class:

template<typename T>
class Grid{
public:
    Grid<T>(int inWidth, int inHeight);
    Grid<T>(const T& src);
    Grid<T>& operator=(const T& rhs);

private:
    T** mCells;
    size_t width;
    size_t height;
};

finally they introduce non-type template parameters and say you can now do this:

template<typename T, size_t WIDTH, size_t HEIGHT>
class Grid{
public:
    Grid<T>();
    Grid<T>(const T& src);
    Grid<T>& operator=(const T& rhs);

private:
    T mCells[WIDTH][HEIGHT];
};

From the book:

In the Grid template class, you could use non-type template parameters to specify the height and width of the grid instead of specifying them in the constructor. The principle advantage to specifying non-type parameters in the template list instead of the constructor is that the values are known before the code is compiled. Recall that the compiler generates code for templatized methods by substituting in the template parameters before compiling. Thus you can use a normal two-dimensional array in your implementation instead of dynamically allocating it.

I don't get all the excitement with this approach regarding the dynamic memory allocation. Firstly does this mean the multidimensional array would be on the stack (because they seem to suggest it wouldnt be dynamically allocated)? I don't understand why you wouldn't want to dynamically allocate the memory on the heap?

Secondly, is there some C++ rule (which I am forgetting) which prohibits declaring a multidimensional array on the stack, hence the excitement with this approach?

I am trying to understand what is the advantage of using non-type template parameters in their example.


Solution

  • Firstly does this mean the multidimensional array would be on the stack (because they seem to suggest it wouldnt be dynamically allocated)?

    As you can see, your array is directly a member, it's not indirected by a pointer.

    T mCells[WIDTH][HEIGHT];
    

    But it wouldn't be correct to say that it's on the stack or the heap since in fact the array is a part of your object and where it is depends on where and how your object is allocated. If the object is allocated on the heap, its array subobject will be too, if the whole object is on the stack, so will the array be.

    I don't understand why you wouldn't want to dynamically allocate the memory on the heap?

    You could. But having a new'd array is both slower and more error-prone (i.e. it should be deleted etc).

    Secondly, is there some C++ rule (which I am forgetting) which prohibits declaring a multidimensional array on the stack, hence the excitement with this approach?

    No. But the size of any array must be a compile-time constant. Non-type template parameters are exactly that - compile time constants. Had they been simply function parameters of an int type, the compiler would not know their value and it would be illegal to create an array (multidimensional or otherwise) on the stack.