Thread: How make function that can take std::vector's of varying dimensions?

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

    How make function that can take std::vector's of varying dimensions?

    I want to make a function that takes std::vector as a parameter but without specifying the number of dimensions. Then it will check how many dimensions inside the function and use loops to get all the data out. How would i do this? Do I have to do something like:

    Code:
    public void getData(std::vector *vec)
    {
       //do work here
    }
    Would that even work? is there a better way?

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    A std::vector has no such thing as "dimensions." It is always one dimensional. Are you talking about vectors of vectors?

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by brewbuck View Post
    A std::vector has no such thing as "dimensions." It is always one dimensional. Are you talking about vectors of vectors?
    Whoops. Yep, sorry about the confusion. I mean I'd like to be able to do something like:

    Code:
    //We've got some variables
    <std::vector<std::vector<int> > nums;
    <std::vector<std::vector<std::vector<int> > > otherNums;
    
    //Put them both into the function
    getData( nums );
    getData( otherNums );
    (And this assumes that getData(...) can be used for ANY
    depth of vectors of vectors, so no overloading of the function would solve it)

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You can do that using function templates. Have you learned function templates?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by CornedBee View Post
    You can do that using function templates. Have you learned function templates?
    No.

    EDIT: Oh, wait. I think you mean templates like:

    Code:
    template <class T>
    
    T DoSmth (T a, T b) 
    {
        //do code here
    }
    
    int main () 
    {
      int i=5, j=6;
      DoSmth<int>(i,j);
      return 0;
    }
    Not sure if that totally solves the problem. Inside the function, how would the code loop through the vectors or vectors? How does it discover how many "levels" there are?

    Thanks!
    Last edited by 6tr6tr; 04-01-2008 at 02:58 PM.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Code:
    template <typename T>
    void getData(const std::vector<T> &data)
    {
      // This is the final recursion. Do something with the data here.
    }
    
    template <typename T>
    void getData(const std::vector< std::vector<T> > &data)
    {
      // This unwraps the vectors.
      for(typename std::vector< std::vector<T> >::const_iterator it = data.begin();
        it != data.end(); ++it)
      {
        getData(*it);
      }
    }
    Last edited by CornedBee; 04-01-2008 at 03:02 PM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    CornedBee, is there a reason for the non-const reference in the second version but the reference to const in the first? Why not make them all const or all not const?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yeah, there is: confusion.
    I'll edit the post.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by CornedBee View Post
    Code:
    template <typename T>
    void getData(const std::vector<T> &data)
    {
      // This is the final recursion. Do something with the data here.
    }
    
    template <typename T>
    void getData(const std::vector< std::vector<T> > &data)
    {
      // This unwraps the vectors.
      for(typename std::vector< std::vector<T> >::const_iterator it = data.begin();
        it != data.end(); ++it)
      {
        getData(*it);
      }
    }
    I apologize for taking your time and really appreciate all your help. I'm a little confused.

    How would that work if it was passed a vector of a vector of a vector of some object? (In other words: <std::vector<std::vector<std::vector<int> > >) Or four levels deep, etc?

    I want a function that can handle anywhere from 1..n levels of vectors without knowing beforehand. That's the code that confuses me a bit (I can write it in Java but am having trouble with C++, sorry).

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The compiler tries to figure out which of the two should be used for std::vector<std::vector<std::vector<int> > >. It can either make T = std::vector<std::vector<int> > and use the first, or it can make T = std::vector<int> and use the second.

    Apparently the rules require that it choose the second because the type used for the argument is closer to the actual parameter type of the second function.

    From there, it calls getData for each element in the outer vector. This means a std::vector<std::vector<int> > is being passed to getData. Again, the compiler can choose between T = std::vector<int> (for the first one) or T = int (for the second one). Again, we are passing a std::vector<std::vector<T> > so that is a closer match, so the second version is used.

    Each element of that vector is then sent to getData, but those would each have the type std::vector<int>. Since that type doesn't match the second function, the first function is used.

  11. #11
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by 6tr6tr View Post
    I apologize for taking your time and really appreciate all your help. I'm a little confused.

    How would that work if it was passed a vector of a vector of a vector of some object? (In other words: <std::vector<std::vector<std::vector<int> > >) Or four levels deep, etc?

    I want a function that can handle anywhere from 1..n levels of vectors without knowing beforehand. That's the code that confuses me a bit (I can write it in Java but am having trouble with C++, sorry).
    I haven't tried this, but I think it should work for n levels because for:
    Code:
    const std::vector< const std::vector<T> >
    T can be anything, including another const std::vector<T>, then that T could be another const std::vector...
    When the loop calls getData() it calls the first version if it's the inner-most level, otherwise it calls itself.

  12. #12
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by CornedBee View Post
    Yeah, there is: confusion.
    I'll edit the post.
    HELP! I wrote the code you gave an it won't compile. For some reason it says that "GetData" has already been defined! Why won't it let me overload the function?

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    What are you doing inside getData? If you're changing data you need to de-constify it. This simple example works for me since the data doesn't change:
    Code:
    #include <iostream>
    #include <vector>
    
    template <typename T>
    void getData(const std::vector<T> &data)
    {
      for(typename std::vector<T>::const_iterator it = data.begin();
        it != data.end(); ++it)
      {
          std::cout << (*it) << ' ';
      }
      std::cout << '\n';
    }
    
    template <typename T>
    void getData(const std::vector< std::vector<T> > &data)
    {
      // This unwraps the vectors.
      for(typename std::vector< std::vector<T> >::const_iterator it = data.begin();
        it != data.end(); ++it)
      {
        getData(*it);
      }
    }
    
    int main()
    {
        std::vector<std::vector<std::vector<int> > > threeD(2,
                             std::vector<std::vector<int> >(3,
                                           std::vector<int>(4, 7)));
        getData(threeD);
    }

  14. #14
    Registered User
    Join Date
    Nov 2006
    Posts
    184
    Quote Originally Posted by Daved View Post
    What are you doing inside getData? If you're changing data you need to de-constify it. This simple example works for me since the data doesn't change:
    Really? it won't compile for me in MS Visual C++. It says:

    'error C2995' : 'GetData' : template function has already been defined.

    EDIT: And when I compile your code, I get the same error! Help, why isn't this working?
    Last edited by 6tr6tr; 04-01-2008 at 04:02 PM.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by 6tr6tr View Post
    Really? it won't compile for me in MS Visual C++. It says:

    'error C2995' : 'GetData' : template function has already been defined.

    EDIT: And when I compile your code, I get the same error! Help, why isn't this working?
    Probably because the compiler sucks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  5. C++ compilation issues
    By Rupan in forum C++ Programming
    Replies: 1
    Last Post: 08-22-2005, 05:45 AM