Thread: Any way to find out how many "dimensions" a vector has?

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    184

    Any way to find out how many "dimensions" a vector has?

    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?

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 6tr6tr View Post
    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.

    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);
    }
    Note that the parameters don't even have names, since they are not used for anything.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by brewbuck View Post
    The drill_down function I posted earlier is easily adapted to do this.

    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);
    }
    Note that the parameters don't even have names, since they are not used for anything.
    Thanks! I was doing something similar to that since you'd posted your code but then I thought I should check if there was a "standard" way/function for this.

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 6tr6tr View Post
    Thanks! I was doing something similar to that since you'd posted your code but then I thought I should check if there was a "standard" way/function for this.
    I just realized my code has a bug in it. You do need a named parameter:

    Code:
    template <typename T>
    int vector_dimensions(const vector<T> &vec_p)
    {
        return 1 + vector_dimensions(vec_p[0]);
    }
    This silliness could be avoided by writing it as a proper metaprogram instead.

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by brewbuck View Post
    I just realized my code has a bug in it. You do need a named parameter:

    Code:
    template <typename T>
    int vector_dimensions(const vector<T> &vec_p)
    {
        return 1 + vector_dimensions(vec_p[0]);
    }
    This silliness could be avoided by writing it as a proper metaprogram instead.
    Thanks, can you explain a bit more what that would entail?

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 6tr6tr View Post
    Thanks, can you explain a bit more what that would entail?
    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:

    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;
    };
    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.

    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:

    Code:
    template <typename T>
    int get_vector_dimensions(const T &vec_p)
    {
        return vector_dimensions<T>::n;
    }
    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).

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by brewbuck View Post
    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).
    WOW. That is REALLY cool! Thanks!!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem building Quake source
    By Silvercord in forum Game Programming
    Replies: 16
    Last Post: 07-11-2010, 09:13 AM
  2. could not find -lwsock32.lib
    By thomas_joyee in forum C++ Programming
    Replies: 8
    Last Post: 07-14-2008, 12:28 PM
  3. How to find O of threads ?
    By jabka in forum C Programming
    Replies: 3
    Last Post: 03-11-2008, 12:25 PM
  4. how do u find 2nd largest number??
    By juancardenas in forum C Programming
    Replies: 8
    Last Post: 02-14-2003, 08:28 AM
  5. Q: Recursion to find all paths of a maze
    By reti in forum C Programming
    Replies: 7
    Last Post: 11-26-2002, 09:28 AM