Thread: Can I dynamically create vectors of multiple depths?

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

    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 );
         }
    }
    Last edited by 6tr6tr; 04-13-2008 at 09:12 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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.
    Last edited by tabstop; 04-13-2008 at 09:27 PM.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by tabstop View Post
    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)

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    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 *>.

  5. #5
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by phantomotap View Post
    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?

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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.)

    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.

    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

  8. #8
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    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

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by 6tr6tr View Post
    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?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linker errors - Multiple Source files
    By nkhambal in forum C Programming
    Replies: 3
    Last Post: 04-24-2005, 02:41 AM
  2. a point of threads to create multiple threads
    By v3dant in forum C Programming
    Replies: 3
    Last Post: 10-06-2004, 09:48 AM
  3. Modeless Dialogs in Multiple threads
    By MrGrieves in forum Windows Programming
    Replies: 0
    Last Post: 06-22-2004, 01:33 PM
  4. Replies: 1
    Last Post: 05-01-2003, 02:52 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM