Thread: I upgraded to g++ 4.2.2 and...

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    271

    I upgraded to g++ 4.2.2 and...

    now some code doesn't work. I upgraded from g++ 4.0.3.

    Here's the offending line of code
    Code:
    some_container::iterator it = 0;
    I'm assuming that it doesn't conform to the standard and that's why it's now giving me an error message.

    So how do you do for iterators what you do for pointers? Like
    Code:
    some_type* T = 0;
    Last edited by cunnus88; 02-03-2008 at 10:20 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What is the exact error message?

    [And your code-tag at the end is missing the / to mark an end-tag]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Unfortunately, I don't have my work computer in front of me right now, so I can't duplicate it, but I think it was something along the lines of how "iterator:perator=()" is undefined for "int"s.

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    I think it was something along the lines of how "iteratorerator=()" is undefined for "int"s.
    well yeah look at what you've got there, it doesn't make sense:
    Code:
    some_container::iterator it = 0;
    that won't work, because 0 or NULL or whatever you're trying to do here isn't a "some_container" object. iterators don't need to be initialized when declaring them, they're already initialized to NULL in their constructor, or rather the pointer they contain (as their private member) is initialized to NULL I should say.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cunnus88 View Post
    So how do you do for iterators what you do for pointers?
    You don't have to do anything. Unlike a pointer, an iterator has a constructor which leaves it in a sane state after you declare it. Just declare it.

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Then how do you check at the end of some procedure whether the iterator was assigned an object or whether it came through untouched? e.g.
    Code:
    if(it != ????)
       do something to it;

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    There's no such thing as a NULL iterator, unlike for pointers. For a given container c, you can use the c.end() iterator for the same purpose.

    Edit: From Stroustrup, TC++PL, page 550:

    An iterator is not a general pointer. Rather, it is an abstraction of the notion of a pointer into an array. There is no concept of a "null iterator." The test to determine whether an iterator points to an element or not is conventionally done by comparing it against the end of its sequence (rather than comparing it against a null element). This notion simplifies many algorithms by removing the need for a special end case and generalizes nicely to sequences of arbitrary types.
    Last edited by robatino; 02-03-2008 at 12:00 PM.

  8. #8
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    But what if my procedure was designed like this:

    Code:
    some_container c1, c2, c3;
    some_container::iterator it;
    
    a_loop {
      if either c1 or c2 or c3 fits some criteria {
        "it" points to an element in either c1 or c2 or c3
      }
      else if none of these fit the criteria {
        leave "it" alone
      }
    }
    
    if "it" hasn't been touched {
      do something else
    }
    if "it" has been touched {
       do something to "it"
    }
    I don't even know what container instance "it" has been linked to. Much less compare ".end()" with "it".

    Of course, I could keep a separate boolean variable to track the change, but I'd like to know if this can be done without creating it.
    Last edited by cunnus88; 02-03-2008 at 11:58 AM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    A workaround: use a boolean flag.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Oct 2005
    Posts
    271
    Thanks, folks. Time to change my code.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Another workaround: if the containers are elements in an array or vector c[0], c[1], c[2], ... then use an index variable that holds the index of whichever element it points to, or a special value if it points to none of them.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cunnus88 View Post
    I don't even know what container instance "it" has been linked to. Much less compare ".end()" with "it".
    Save a copy of "it" before you start. Then compare to see if it changed at the end.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by brewbuck View Post
    Save a copy of "it" before you start. Then compare to see if it changed at the end.
    The only problem is that it needs to be initialized to some special value so it can be determined whether it changed, and with iterators any valid value must be associated with a specific container. One workaround would be to define a dummy container c of zero size, and set it to c.end().

    Edit: Ignore what I just said. Comparing iterators to different containers is undefined behavior, so it won't work (not reliably, anyway). You need to know in advance which container (if any) it points to before you do anything with it. Use either the boolean flag or the index method mentioned above to implement this.
    Last edited by robatino; 02-03-2008 at 12:49 PM.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    with iterators any valid value must be associated with a specific container
    Not entirely true, e.g., the stream iterators have a "end of stream" default value not associated with a specific container, unless you consider the stream a container.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    cunnus88 what are c1 c2 and c3?

    Are they:

    1. different elements of the same container?

    2. different containers of the same type?

    3. different containers of different types?

    If it's 1, then your iterator can be compared to another iterator.

    If it's 2 or 3, then iterators aren't the issue, the algorithm needs refinement.

Popular pages Recent additions subscribe to a feed