Reputation: 4869
I don't understand the following:
#include <iostream>
#include <vector>
using namespace std;
class Date {
public:
Date(int y, int m) {
year = y;
month = m;
}
int year;
int month;
};
int main() {
vector<pair<Date, Date> > ranges;
Date date1 = Date(2000, 1);
Date date2 = Date(2000, 2);
ranges.push_back(pair<Date, Date>(date1, date2));
for (vector<pair<Date, Date> >::iterator it = ranges.begin(); it != ranges.end(); ++it) {
(*it).first.year = 2002;
pair<Date, Date> range = *it;
range.first.year = 2001;
}
cout << ranges[0].first.year << endl;
}
When I run this, "2002" outputs, though I expected "2001".
It seems that casting an iterator does not work as I expected. I can access range
fine, and read its variables, but I cannot change them - or at least, the changes don't stick.
I've fixed my problem by using (*it)
instead of casting, but I'd like to know why my casting does not work.
Upvotes: 0
Views: 1180
Reputation: 310950
In the loop
for (vector<pair<Date, Date> >::iterator it = ranges.begin(); it != ranges.end(); ++it) {
(*it).first.year = 2002;
pair<Date, Date> range = *it;
range.first.year = 2001;
}
range
is a local variable of the loop. In each iteration of the loop (there is only one iteration because the vector contains only one element) this variable is initialized by a copy of the value of the element of the vector. So any changes of this local variable do not influence on the elements of the vector. The vector itself was not changed.
Instead of these two lines
pair<Date, Date> range = *it;
range.first.year = 2001;
you could write simply
( *it ).first.year = 2001;
In this case you would directly change the element of the vector.
Or the other way to change the value of an element of the vector is to use a reference to the element instead of creating a separate object. For example
for (vector<pair<Date, Date> >::iterator it = ranges.begin(); it != ranges.end(); ++it) {
(*it).first.year = 2002;
pair<Date, Date> &range = *it;
range.first.year = 2001;
}
In this case as the reference is used the original element of the vector will be changed.
Upvotes: 1
Reputation: 10358
I recommend using range-based for loops instead, like this:
for (auto& range : ranges)
{
...
range.first.year = 2001;
...
}
You can use a reference, like in the example above, and modify the collection directly.
Upvotes: 1