Two-dimensional array in C++.
Version of 17 Mar 2017.
Dave Barber's other pages.

Class two_dim, below, is a general-purpose two-dimensional array in C++. The size is determined at run time, when the array is constructed. After that, the size cannot be changed. Subscripting is done with the at() function, which ensures that parameters are in range.

This differs significantly from a std::vector< std::vector<component> >, where the inner vectors need not all be the same size, and the size of any vector can be changed at any time after construction. Rather, two_dim has behavior closer to that of the traditional two dimensional array as in Fortran.

For three dimensions, see this.

#include <iostream>
#include <vector>
#include <stdexcept>

template <typename component>
class two_dim {
    int rows, cols;
    std::vector <component> guts;
	
    int subs (int const r, int const c) const {
        if (r < 0)
            throw std::out_of_range ("two_dim::row_range_check");	
        if (r >= rows)
            throw std::out_of_range ("two_dim::row_range_check");	
        if (c < 0)
            throw std::out_of_range ("two_dim::col_range_check");	
        if (c >= cols)
            throw std::out_of_range ("two_dim::col_range_check");	
        return r * cols + c;
    }	
public:	
    two_dim (int const r, int const c, 
             component const & def = component() ) :
        rows {r}, cols {c},
        guts (rows * cols, def)
    {  }
	
    component & at (int const r, int const c)
        { return guts.at (subs (r, c)); }
	
    component const & at (int const r, int const c) const
        { return guts.at (subs (r, c)); }
	
    int size  () const { return rows * cols; }
    int size0 () const { return rows; }
    int size1 () const { return cols; }
};	

int main () {
    // demonstrate the array

    int high;
    int wide;
	
    std::cout << "\n how many rows? ";
    std::cin >> high;
	
    std::cout << "\n how many columns? ";
    std::cin >> wide;
	
    two_dim<int> table {high, wide};
	
    // load table with some values that form a pattern
    for (int h {0}; h < high; ++h)
        for (int w {0}; w < wide; ++w)
            table.at (h, w) = 100 * (h + 1) + 10 * (w + 1);
	
    // see what you've got:
    for (int h {0}; h < high; ++h) {
        for (int w {0}; w < wide; ++w) {
            std::cout << "\n table.at(" << h;
            std::cout << "," << w;
            std::cout << ") = " << table.at(h, w);
        }	
        std::cout << "\n";
    }	

    std::cout << "\n there are " << table.size0() << " rows";
    std::cout << " and " << table.size1() << " columns for a total of ";
    std::cout << table.size() << " components";
    return 0;
}