Computing the number of dimensions of an array, vector, or deque

The following program demonstrates two different ways of computing the number of dimensions of a variable or data type. The first method, implemented using a template function signature called "dims(x)", is used to determine the number of dimensions of (a possibly multi-dimensional) array.

You basically call it like this:

    int array[4][5][6];

    int dimensions = dims(array);

    // dimensions now contains 3.
Or like this:
    vector< vector<int [4][5][6]> > flarg;

    int dimensions = dims(flarg);

    // dimensions now contains 5.
In both cases, the dims() function computes the number of dimensions of the variable passed into it by const &.

Alternatively, if you need the information at compile time, you can use the other mechanism: template< class T> struct DimCountClass{}. This mechanism uses template specialization to create data types (classes) which have a member called "count" which is the number of dimensions of class T passed in.

There are some advantages for both approaches. However, if you need to declare an array whose size is the number of dimensions of some other type, then you will have to use the DimCountClass mechanism. For example:


    typedef  vector< vector<int [4][5][6]> > flargType;

    flargType flarg;

    static int flargDimInfo[ DimCountClass< flargType >::count ];

    // flargDimInfo has 5 elements.

And finally, here is the code that implements the dims() function and the DimCountClass discussed above: #include <iostream> #include <vector> using namespace std; inline int dimCount(void const *) // // compute the number of dimensions of non-arrays // { return 0; } template<class T, size_t N> inline int dimCount(T (*ptr)[N]) // // return the number of dimensions of an array for which you have a // pointer -- note the input parameter must be the address of the array // not the address of the first element there of: // // this: &array // not: &array[0] // // There's probably a way to do this entirely at compile time -- but I'm too // lazy right now. { T* p(0); return 1 + dimCount(p); } template<class T> inline int dimCount( std::vector< T > const *) { T* p(0); return 1 + dimCount(p); } template<class T> inline int dims(T const &x) // // wrapper for dimCount that makes the interface cleaner // { return dimCount(&x); } template<class T, size_t COUNT=0> struct DimCountClass // // This class' sole purpose is to define a value specific to its // template parameter -- the value, held in member count, is the // number of array dimension that the T parameter has. By default // the answer is 0 -- unless a template specialization is made for // a given container, it will be assumed that the class T, is not // an array or container. // { enum constants { count=COUNT }; }; template<class T> struct DimCountClass< vector<T> > // // This specialization of DimCountClass, documented above, defines // the number of dimensions for vector<T> objects -- which is to say, // one more than the number of dimensions of T // { enum constants { count=1+DimCountClass< T >::count }; }; template<class T, size_t N> struct DimCountClass< T[N] > // // This specialization of DimCountClass, documented above, defines // the number of dimensions for builtin arrays -- which is 1 more than // the number of dimensions of class T objects. This also works for // multi-dimensional arrays. // { enum constants { count=1+DimCountClass< T >::count }; }; int main() { int s; int a1d[4]; int a2d[3][5]; int a3d[2][7][9]; cout << "array dims: " << dims(s) << ", " << dims(a1d) << ", " << dims(a2d) << ", " << dims(a3d) << endl; vector<int> vi0; vector<int[4]> vi1; vector<int[5][6]> vi2; vector<vector<int[10][2]> > vi3; cout << "vector dims: " << dims(vi0) << ", " << dims(vi1) << ", " << dims(vi2) << ", " << dims(vi3) << endl; cout << "comptime dims: " << DimCountClass<int>::count << ", " << DimCountClass<vector<int> >::count << ", " << DimCountClass< int [3][5] >::count << ", " << DimCountClass< vector< int [3][5] > >::count << endl; static int dimInfo[ DimCountClass< vector< int [3][5] > >::count ]; cout << "array[ dims ]: " << sizeof(dimInfo) / sizeof(int) << endl; }