Problem with generic function

This is a discussion on Problem with generic function within the C++ Programming forums, part of the General Programming Boards category; Well first let me tell you that your problems go much deeper than your template parameter woes. The logic in ...

  1. #16
    Registered User
    Join Date
    Jan 2008
    Posts
    287
    Well first let me tell you that your problems go much deeper than your template parameter woes. The logic in your program is a little messed up.

    However, assuming you'll be able to fix that on your own once you overcome your template problems, try this:

    Code:
    #ifndef SSCR_H_INCLUDED
    #define SSCR_H_INCLUDED
    
    #include <iostream>
    #include <vector>
    
    template <class T>
    void sscr(std::vector<std::vector<T> > v)
    {
       typename std::vector<std::vector<T> >::iterator i;
       typename std::vector<T>::iterator j;
       
       for (i = v.begin(); i != v.end(); i++) {
          for (j = i->begin(); j != i->end(); j++)
             std::cout << *j << " ";
          std::cout << std::endl;
       }
    }
    
    #endif // SSCR_H_INCLUDED
    It limits you to passing in a vector of vectors, but I think that should be a pretty reasonable expectation.

    Oh and there's no point having this function return 0. Just return 0 from your main function after you call this.

  2. #17
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    You're new to C++; have you studied pointers yet? An iterator is basically a pointer.

    Maybe you should not be concerned with iterators yet, but simply use the operator[] or the member function .at for your vector.

  3. #18
    Registered User
    Join Date
    Aug 2008
    Posts
    14

    Lightbulb It Worked!

    Hello MarkZWEERS,

    Hey man, it worked. Now let me ask you some doubts regarding some of your statements.

    1. These lines represent the first statements in the definition of the generic function.

    Code:
    template <class T>
    void sscr(std::vector<std::vector<T> > v)
    I understand that. But my doubt is I thought the compiler was supposed to be smart enough to decipher the type of the class T and so, there was no need for explicitly showing the type as you are doing it in the second line. Can you comment something about what you know about this?

    2. If I am not wrong, in this line,

    Code:
    for (j = i->begin(); j != i->end(); j++)
    you dereferenciate the ith iterator ans assign it to the iterator for the inner loop. This seems logical, but I previously tried to do that and another person in the forum replied that it could lead to an infinite loop. Could you please explain shortly what C++ is really doing there?

    3. About your last post,

    You're new to C++; have you studied pointers yet? An iterator is basically a pointer.

    Maybe you should not be concerned with iterators yet, but simply use the operator[] or the member function .at for your vector.
    It is fine. I understand what they are, although I don't domain them yet. By answering question 2 you will help me a lot in that process.

    Thanks for your patience, MarkZWEERS.

  4. #19
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    I thought the compiler was supposed to be smart enough to decipher the type of the class T
    But if you declare a class template, you should indicate which "thing" should be parametrised. Parameter deduction comes in play when you use the class template (as in overloading an operator, for example).

    for (i = v.begin(); i != v.end(); i++) {
    for (j = i->begin(); j != i->end(); j++)
    Nothing surprising in this code snippet: 'i' is the iterator (let's say pointer). So to acces its member functions, you should use '->' in 'i->begin()' whereas v is an object so you use '.' as in 'v.begin()'.

    If then you want the value of where 'j' points to, you de-reference the iterator with '*j'.

    Of course you could also do
    for (i = v.begin(); i != v.end(); i++) {
    for (j = (*i).begin(); j != (*i).end(); j++)
    but the de-referencing in the loop declaration is expensive and entirely useless overhead.
    Last edited by MarkZWEERS; 08-16-2008 at 04:11 PM.

  5. #20
    Registered User
    Join Date
    Aug 2008
    Posts
    14

    Smile End Of Thread

    Thank you so much MarkZWEERS. You have helped me a lot in my code and also in my overall understanding of the tools involved.

    I think your answer marks the final of this thread.

    Bye.

  6. #21
    Registered User
    Join Date
    Jan 2008
    Posts
    287
    Quote Originally Posted by MarkZWEERS View Post
    but the de-referencing in the loop declaration is expensive and entirely useless overhead.
    Wait what? Now I'm confused. I could swear that (*i).begin() and i->begin() were exactly identical statements. The arrow operator performs the dereferencing for you. Am I mistaken? Or is this just some optimization that only applies to iterators?

  7. #22
    Registered User
    Join Date
    Aug 2008
    Posts
    14

    I thought the same!

    Hello arpsmack,

    I thought the same. In the book I used to learn C++ (Koenig and Moo. Accelerated C++ Practical Programming by Example. Addison Wesley 2000) they said the two things were the same. They explained:

    Code:
    it->x
    
    Equivalent to (*it).x, which returns the member x denoted by the object obtained by dereferencing the iterator it. Same precedence as the . operator.
    At any rate, thanks to you for the code and to MarkZWEERS for the explanation. Just a clarification: This is just an exercise for future application in my research, so I will not use directly your code. I am just training myself in C++ .

    Bye.

  8. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    20,968
    Where user defined types are concerned, they are not the same, though they should behave as if they were the same.

    (*i).end() is equivalent to: i.operator*().end()
    i->end() is equivalent to: i.operator->()->end()

    That said, I think that MarkZWEERS is wrong to consider (*i).end() as resulting in "expensive and entirely useless overhead" compared to i->end() since i->end() also has a similiar function call penalty which can be avoided by caching the iterator returned (though it is a constant time overhead).
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #24
    Registered User
    Join Date
    Jan 2008
    Posts
    287
    Ok that's what I thought. Thanks for the clarification laserlight.

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. wxWidgets link problem
    By cboard_member in forum C++ Programming
    Replies: 2
    Last Post: 02-11-2006, 01:36 PM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 01:28 PM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. Replies: 5
    Last Post: 02-08-2003, 06:42 PM
  5. I need help with passing pointers in function calls
    By vien_mti in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 10:00 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21