Andy Isbell
Andy Isbell

Reputation: 259

Trouble with reference/value mixups?

I'm tweaking a function that reverses the values of a container denoted by iterators begin and end.

Why does this work:

template<class Bi> void reverse(Bi begin, Bi end){
    while (begin!= end) {
        --end;
        if (begin != end)
            swap(*begin++, *end);
    }
}

but not this?

template<class Bi> void reverse(Bi begin, Bi end){
    while (begin != end) {
        --end;
        if (begin != end){
            Bi temp = begin;
            Bi temp2 = end;
            *begin = *temp2;
            *end = *temp;
            begin++;
        }
    }
}

This compiles just fine, but I must be misunderstanding something about assigning iterators equal to each other, because when I go to reverse a vector, say, of values 1 through 5, I end up with 5 through 1 in the first one, but the second one yields the values 5, 4, 3, 4, 5. I don't understand this behavior, what's wrong here?

Upvotes: 1

Views: 41

Answers (2)

jogojapan
jogojapan

Reputation: 69967

The problem is here:

Bi temp = begin;
Bi temp2 = end;

The first line assigns the iterator position begin refers to to temp. So now temp refers to the same position in the container as begin.

Then you modify the value stored at that position:

*begin = *temp2;

Of course, temp still refers to that position, therefore *temp now also represents the modified value.

Therefore, this:

*end = *temp;

assigns the wrong value to *end (in fact, it does not assign any new value at all).

Upvotes: 2

You are mixing the concept of the iterator and the value. In the second approach you copy the iterators, but not the values: begin and temp refer to the same element, so do end and temp2. When you do *begin = *temp2; the first element is set to 5, when you later do *end=*temp the first element (already set to 5) is copied to the last position, leaving both the first and the last position being 5.

What you need to do is copying the values, not the iterators.

Upvotes: 4

Related Questions