Something on these lines:
template<class Y>
struct s
{
enum {dims = 0};
};
template<class Y>
struct s<std::vector<Y>>
{
enum {dims = s<Y>::dims + 1};
};
Then for example,
std::vector<std::vector<double> > x;
int n = s<decltype(x)>::dims; /*n will be 2 in this case*/
Has the attractive property that all the evaluations are at compile time.