You need something like this:
// Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <map>
/**
 * This is the default container class using in Matrix. This can easily
 * be changed through template paramenters of Matrix. See below for more
 * about what the container is used for.
 */
template <typename T>
class DefaultContainer : public std::map<int, T>
{
};
/**
 * Matrix is a class template that implements a multi-dimensional storage
 * of specific type T. The Container is responsible to how these Ts will
 * be stored and retrieved from memory.
 * This is the general case for dimensions > 1. For the simple case of 1
 * dimension see below.
 */
template <typename T,
          int dimensions,
          template <typename> class Container = DefaultContainer
          >
class Matrix
{
    /**
     * A Matrix of n dimensions is actually an array of matrices each has
     * n-1 dimensions.
     * This is what happens here. m_data, in its simple case, is an array
     * of itemTypes each of them is defined as a Matrix of dimensions-1
     */ 
    typedef Matrix<T,dimensions-1, Container> itemType;
    Container<itemType> m_data;
public:
    /**
     * This returns an item of the array m_data which is probably a matrix
     * of less dimensions that can be further accessed be the same operator
     * for resolving another dimension.
     */
    itemType& operator[](int idx)
    {
        return m_data[idx];
    }
    const itemType& operator[](int idx) const
    {
        return m_data[idx];
    }
};
/**
 * This is the simple case of a one-dimensional matrix which is technically
 * an array in its simplest case.
 */
template <typename T,
          template <typename> class Container
          >
class Matrix<T,1,Container>
{
    /**
     * Here we are defining an array of itemType which is defined to be T.
     * so we are actually defining an array of T.
     */
    typedef T itemType;
    Container<itemType> m_data;
public:
    itemType& operator[](int idx)
    {
        return m_data[idx];
    }
    const itemType& operator[](int idx) const
    {
        return m_data[idx];
    }
};
#endif // MATRIX_H
Example Usage:
#include <iostream>
#include "matrix.h"
int main(int argc, char *argv[])
{
    Matrix<int, 2> m;
    /**
     * m here is a two-dimensional matrix.
     * m[0] is resolving the first dimension of the matrix. it is like
     * getting the first row which should be an array of items. And this
     * is actually what m[0] returns. It returns a one-dimensional matrix
     * (an array) whose items can also be accessed using operator[] to
     * get one of those items m[0][1].
     */
    m[0][1] = 1;
    m[1][2] = 5;
    std::cout << m[0][1];
    std::cout << m[1][2];
    return 0;
}