天天看點

特殊的forward_list操作

為了了解forward_list為什麼有特殊版本的添加和删除操作,考慮當我們從一個單向連結清單中删除一個元素時會發生什麼。當添加或删除一個元素時,删除或添加的元素之前的那個元素的後繼會發生變化。為了添加或删除一個元素,我們需要通路其前驅,以便改變前驅改變前驅的連結。但是,forward_list是單向連結清單。在一個單向連結清單中,沒有簡單的方法來擷取一個元素的前驅,出于這個原因,在一個forward_list中添加或删除元素的操作是通過改變給定元素之後的元素來完成的。這樣,我們總是可以通路到被添加或删除元素所影響的元素。

由于這些操作與其他容器上的操作有實作方式不同,forward_list并未定義insert、emplace和erase,而是定義了名為insert_after、emplace_after和erase_after的操作。為了支援這些操作,forward_list也定義了before_begin,它傳回一個首前疊代器。這個疊代器允許我們在連結清單首元素之前并不存在的元素“之後”添加或删除元素(亦即在連結清單首元素之前添加删除元素)。

在forward_list中插入或删除元素的操作

lst.before_begin()      傳回指向連結清單首元素之前并不存在的元素的疊代器,此疊代器不能解引用。

lst.cbefore_begin()      cbefore_begin()傳回一個const_iterator

lst.insert_after(p,t)        在疊代器p之後的位置插入元素。t是一個對象,n是數量,b和e是表示範圍的一對疊代器(b和e不能指向lst内),il是一個花括号清單。傳回一個指向最後一個插入lst.insert_after(p,n,t)     元素的疊代器。如果範圍為空,則傳回p,若p為尾後疊代器,則函數行為未定義。

lst.insert_after(p,b,e)

lst.insert_after(p,il)

emplace_after(p,args)    使用args在p指定的位置之後建立一個元素,傳回一個指向這個新元素的疊代器。若p為尾後疊代器,則函數的行為未定義

lst.erase_after(p)       删除p指向的位置之後的元素,或删除從b之後直到(但不包含)e之間的元素。傳回一個指向被删除元素之後元素的疊代器,若不存在這樣的元素,則傳回尾後疊代

              器,如果p指向lst的尾元素或者是一個尾後疊代器,則函數的行為未定義

當在forward_list中添加或删除元素時,我們必須關注兩個疊代器——一個指向我們要處理的元素,另一個指向其前驅。例如,我們從list中删除奇數元素的循環程式,将其改為從forward_list中删除元素:

此例中,curr表示我們要處理的元素,prev表示curr的前驅。調用begin來初始化curr,這樣第一步循環就會檢查第一個元素是否是奇數。我們用before_begin來初始化prev,它傳回指向curr之前不存在的元素的疊代器。

當找到奇數元素後,我們将prev傳遞給erase_after,此調用将prev之後的元素删除,即,删除curr指向的元素。然後我們将curr置為erase_after的傳回值,使得curr指向序列中下一個元素,prev保持不變,仍指向(新)curr之前的元素。如果curr指向的元素不是奇數,在else中我們将兩個疊代器都向前移動。