Is there a way at runtime to find out how many dimensions a vector has? For example, vector<vector<int> > would be a two-dimensional vector (so this is diff. from its size() ). Is there any way to discover that at runtime?
Printable View
Is there a way at runtime to find out how many dimensions a vector has? For example, vector<vector<int> > would be a two-dimensional vector (so this is diff. from its size() ). Is there any way to discover that at runtime?
The drill_down function I posted earlier is easily adapted to do this.
Note that the parameters don't even have names, since they are not used for anything.Code:template <typename T>
int vector_dimensions(const T &)
{
return 0;
}
template <typename T>
int vector_dimensions(const vector<T> &)
{
return 1 + vector_dimensions(typename vector<T>::value_type);
}
I just realized my code has a bug in it. You do need a named parameter:
This silliness could be avoided by writing it as a proper metaprogram instead.Code:template <typename T>
int vector_dimensions(const vector<T> &vec_p)
{
return 1 + vector_dimensions(vec_p[0]);
}
Well, doing this with functions forces you to pass in a specific instance, when it isn't really necessary (actually, it's not necessary for the function version either, but you'd have to specify the template parameter explicitly instead of letting the compiler deduce it from the argument). A metaprogram would be written with class templates instead of function templates:
This is superior to the function version in a few ways. First, it no longer requires you to pass an instance. You just refer to vector_dimensions<some_type>::n. Second, it is more likely that the compiler will be able to optimize this completely statically, at compile time. With the function implementation the possibility remains that it all happens at runtime, which would be inefficient and unnecessary.Code:template <typename T>
struct vector_dimensions
{
static const int n = 0;
};
template <typename T>
struct vector_dimensions<vector<T> >
{
static const int n = 1 + vector_dimensions<T>::n;
};
The only downside is having to specify the type explicitly even if you DO have an object at hand. That can be addressed by pairing the vector_dimensions<> template with a small helper function:
So if all you have is a type, you can get the dimensions through vector_dimensions<T>::n. If you have an actual instance, call it x, you can just say get_vector_dimensions(x).Code:template <typename T>
int get_vector_dimensions(const T &vec_p)
{
return vector_dimensions<T>::n;
}