2014-11-25 137 views
0

的我不明白以下幾點:鑄造一個迭代一對對象

#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; 
} 

當我運行此,「2002」的輸出,但我預計「2001」。

似乎鑄造一個迭代器不能按我的預期工作。我可以訪問range,並且讀取它的變量,但是我不能改變它們 - 或者至少,這些變化不會粘住。

我已經通過使用(*it)解決了我的問題,而不是投射,但我想知道爲什麼我的投射不起作用。

+1

您正在更改副本上的值。 – imreal 2014-11-25 08:16:38

+1

'範圍'是本地副本。對其的修改不會影響矢量的內容。 – juanchopanza 2014-11-25 08:17:04

+0

它也複製對象的內容?有沒有一種方法可以將我的迭代器轉換成'pair '而不用引用'* it'? – Crummy 2014-11-25 08:21:26

回答

1

在循環

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是循環的局部變量。在循環的每次迭代中(只有一次迭代,因爲該向量只包含一個元素),此變量由向量元素值的副本初始化。所以這個局部變量的任何變化都不會影響向量的元素。載體本身沒有改變。

相反這兩條線

pair<Date, Date> range = *it; 
    range.first.year = 2001; 

的,你可以寫簡單的

(*it).first.year = 2001; 

在這種情況下,你會直接改變向量的元素。

或者更改矢量元素值的另一種方法是使用對元素的引用,而不是創建單獨的對象。例如

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; 
} 

在作爲基準使用向量的原始元素這種情況下將被改變。

+0

謝謝,最終你的選擇是我的目標。非常感激。 – Crummy 2014-11-25 08:43:03

1

我建議使用for循環,而不是基於範圍的,就像這樣:

for (auto& range : ranges) 
{ 
    ... 
    range.first.year = 2001; 
    ... 
} 

可以在例子中使用的參考,像上面,並直接修改集合。

+0

在我實際的代碼中,當我迭代它(刪除元素)時,我正在修改列表,因此無法使用此樣式。 – Crummy 2014-11-25 08:33:39