CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Jul 2007
    Posts
    249

    Red face Iterator Increment and decrement

    Hi,
    I found the following description for iterator

    The use of the increment and decrement operators of iterators includes a strange problem. In general, you can increment and decrement temporary iterators. However, for vectors and trings, you typically can't. Consider the following vector example:
    std::vector<int> coll;
    ...
    //sort, starting with the second element
    // - NONPORTABLE version
    if (coll.size() > 1) {
    coll.sort (++coll.begin(), coll.end());
    }
    Typically, the compilation of sort() fails. However, if you use, for example, a deque rather than a vector, it will compile. It might compile even with vectors, depending on the implementation of class vector.
    The reason for this strange problem lies in the fact that vector iterators are typically implemented as ordinary pointers. And for all fundamental data types, such as pointers, you are not allowed to modify temporary values. For structures and classes, however, it is allowed. Thus, if the iterator is implemented as an ordinary pointer, the compilation fails; if implemented as a class, it succeeds. It always works with deques, lists, sets, and maps because you can't implement iterators as ordinary pointers for them.

    I am not able to grasp some points like
    What is temporary iterator?
    Why it will not work for vector and work for deque?
    What is this mean ---" for all fundamental data types, such as pointers, you are not allowed to modify temporary values. For structures and classes, however, it is allowed. "

    Please help!!!

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Iterator Increment and decrement

    >> What is temporary iterator?

    temporary objects are created as a byproduct of function invokations, conversions, some initializations and in some other occasions whenever you need to create an object in order to complete the evaluation of an expression.

    For example, the code "myvector v; myvector::iterator i = v.begin();" does not create a temporary because the object named "i" is directly created; whereas in order to evaluate the code "myvector v; myvector::iterator i = v.begin() + 2;" you need an object of myvector::iterator type in order to invoke the "+" operator whose result will in turn becomes the instance "i".

    >> Why it will not work for vector and work for deque?
    >> What is this mean ---" for all fundamental data types, such as pointers, you are not allowed to modify temporary values. For structures and classes, however, it is allowed. "

    to answer this question you should understand the reletionship between temporaries and r-values, take a look here.

    Indeed, you'll see that temporaries are always rvalues but can be modifiable rvalues or unmodifiable rvalues. To the former belong mainly temporaries of non const class type ( for example: "vector<int> f(); ... int x = f().pop_back().back();" creates a temporay vector and returns its second-last element ); to the latter belong temporaries of const class type ( the code above with "const vector<int> f()" won't compile... ) and of foundamental type (both const and non const). Therefore the code "int f(); ... int x = ++f();" won't compile.

    Now, vector iterators are often pointers, which are foundamental types; therefore "++coll.begin()" is illegal.

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Iterator Increment and decrement

    This is kind of a non-problem, as catching the temporary value in a new variable and incrementing that instead will net the same result. If the return value can't be incremented, you'll get the same result. If the return value can be incremented, you'll end up with the same assembled code anyways (The return value of begin() is constructed directly into your temp variable, eliding away the cost of the copy).

    So you might as well always write:

    Code:
    if (coll.size() > 1) {
        std::vector<...>::iterator first = coll.begin();
        ++first;
        coll.sort (first, coll.end());
       }
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured