# Can I dynamically create vectors of multiple depths?

• 04-13-2008
6tr6tr
Can I dynamically create vectors of multiple depths?
Is there a way to do something *like* this?

Code:

```template <typename T> vector<T>* addDepth(T) {     return new vector<T>; } ...a templated meth... {     //Create multi-depth vector based on length     void* vec;     int length = getLength( obj );     for ( int i = 0; i < length; i++ )     {           if ( i == 0 ) vec = addDepth( someValue );           else vec = addDepth( vec );     } }```
• 04-13-2008
tabstop
I don't think you can use typenames as arguments to function? (Edit: never mind.) And for that matter, I have no idea what you're trying to accomplish. Even just reading it as pseudocode, it reduces to vec = new vector<T>. ETA: Although it's possible I don't read pseudocode well.

Are you trying to build a vector< vector <vector <vector ... <T>>>>>>>? The tricky part I'm seeing is to be sure that you don't start creating vector <void *> instead.
• 04-13-2008
6tr6tr
Quote:

Originally Posted by tabstop
I don't think you can use typenames as arguments to function? And for that matter, I have no idea what you're trying to accomplish. Even just reading it as pseudocode, it reduces to vec = new vector<T>.

Are you trying to build a vector< vector <vector <vector ... <T>>>>>>>?

Yes, (and the code does actually compile and it actually can create a vector of a vector of a vector that I can put values in and loop through)
• 04-13-2008
tabstop
If it's working for you, then great. I was looking at this:
Code:

```#include <iostream> #include <string> #include <vector> #include <typeinfo> using namespace std; template <typename T> vector<T>* addDepth(T x) {     cout << typeid(vector<T>).name() << endl;     return new vector<T>; } int main(void) {     void *vec;     for (int i=0; i < 5; i++) {         if (i==0) addDepth(5);         else addDepth(vec);     }     cout << typeid(vec).name() << endl;     return 0; }```
and the output was
Code:

```St6vectorIiSaIiEE St6vectorIPvSaIS0_EE St6vectorIPvSaIS0_EE St6vectorIPvSaIS0_EE St6vectorIPvSaIS0_EE Pv```
which is suitably cryptic but I'm pretty sure that I end up with just vector<void *>.
• 04-13-2008
phantomotap
Quote:

Yes, (and the code does actually compile and it actually can create a vector of a vector of a vector that I can put values in and loop through)
Not that code; that code doesn't do anything of the sort. The formal parameters to a template, 'std::vector<this_stuff_here>', must be known at compile time.

At best you can create the illusion of this behavior by creating the 'nest' at compile-time to some maximum depth and installing a "watcher", using 'typeid', and return a heaver nested instance, if one is available.

Soma
• 04-13-2008
6tr6tr
Quote:

Originally Posted by phantomotap
Not that code; that code doesn't do anything of the sort. The formal parameters to a template, 'std::vector<this_stuff_here>', must be known at compile time.

At best you can create the illusion of this behavior by creating the 'nest' at compile-time to some maximum depth and installing a "watcher", using 'typeid', and return a heaver nested instance, if one is available.

Soma

No, it really does work. Try it with an integer being passed in to "addDepth" and then put some vectors into it (and some data) and then loop through the final vectors (casting it to vector<vector, etc) and you'll see it works (use ::const_iterator()).

But whether it works or not isn't my question. I'm wondering is there a good way to dynamically create a vector of vectors?
• 04-14-2008
phantomotap
Quote:

No, it really does work.
No. It does not work. It can not work. (If you are using Ch or something like it and that actually works, then you are not programming in C++, but something that may resemble C++ very closely.)

Quote:

Try it with an integer being passed in to "addDepth" and then put some vectors into it (and some data) and then loop through the final vectors (casting it to vector<vector, etc) and you'll see it works (use ::const_iterator()).
There is no need to try it; it can't work. Further more, you have no way of knowing what to cast it too. Think about it! If I 'addDepth' three times the cast would be 'std::vector<std::vector<std::vector<int>>>'. If I 'addDepth' four times the cast would be 'std::vector<std::vector<std::vector<std::vector<i nt>>>>'.

Trust me on this, it does not work. It may appear to work. It only appears to work if it even really does appear to work. (Which I don't believe.) I'll even explain why it may appear to work: except for the 'std::vector<bool>' specializations all 'std::vector<?>'s may be the same size and have the same method table; because most compilers will compile the entire template, minus template member functions, the moment it sees even a pointer to an instance; most modern operating systems will donate a certain chunk of memory whether you need it or not; the native overhead of 'std::vector<?>' may happen to be the same size the target, read final, element type.

I guarantee you, even if, in the unlikely event, that your machine allows for this concatenation of perfect events, it will eventually fail to mesh with what the correct type is attempting to do... and it will destroy the universe.

Quote:

I'm wondering is there a good way to dynamically create a vector of vectors?
This is why I don't believe your example even appears to work. (I know it can't work; here I'm only interested in the possible appearance of success.) If it worked, this would be the best, indeed perfect, way to create dynamically... anything. If this worked, which it doesn't, a tiny bit of meta-programming would allow it to work with any other container of anything.

If you are using C++ and choose to develop your own object system paralleling that of Objective-C then you could do this, but only because every type is capable of telling every other type exactly what it is.

If you are using C++ and choose templates you can only create nested containers, such as provided by the STL, at compile-time up to some maximum nesting depth and distribute them at runtime. Strangely enough, I've already told you this.

Soma
• 04-14-2008
phantomotap
Since the post by tabstop didn't illuminate:

Code:

```#include <iostream> #include <string> #include <vector> #include <typeinfo> #include <cxxabi.h> using namespace std; template <typename T> vector<T>* addDepth(T x) {     int status(0);     cout << abi::__cxa_demangle(typeid(vector<T>).name(), 0, 0, &status) << "\n\n";     return new vector<T>; } template <typename T> vector<T> mangevector(const T & t) {     int status(0);     cout << abi::__cxa_demangle(typeid(vector<T>).name(), 0, 0, &status) << "\n\n";     return vector<T>(); } int main(void) {     void *vec;     for (int i=0; i < 5; i++) {         if (i==0) addDepth(5);         else addDepth(vec);     }     int status(0);     cout << abi::__cxa_demangle(typeid(vec).name(), 0, 0, &status) << "\n\n";     mangevector(mangevector(mangevector(mangevector(mangevector(vector<int>())))));     return 0; }```
notice the rather... obvious difference between what you think you are getting and what you are really getting.

(Feel free to remove the G++ '
Code:

`abi::__cxa_demangle(typeid(vec).name(), 0, 0, &status)`
' in favor of '
Code:

`typeid(vec).name()`
' for other compilers.)

Soma
• 04-14-2008
iMalc
Quote:

Originally Posted by 6tr6tr
But whether it works or not isn't my question. I'm wondering is there a good way to dynamically create a vector of vectors?

It probably does not make sense to want to create a heirarchy of vectors of an unknown number of dimensions.
If you really needed to do so then you would make the structure inside the vector be some kind of variant, i.e. something that is either another vector or a base type or whatever depending upon some type flag contained within. Basically you would mirror the SAFEARRAY and VARIANT types of OLE.
Or you could put everything in a single vector, and use math on the indexes to access items in some predetermined number of dimensions.

Perhaps you could first illustrate the need to do such a thing?