[英]What's the difference between iterator and back_insert_iterator?
如果隨機訪問迭代器可以用於訪問相對於它們指向的元素的任意偏移位置的元素(不知何故像指針),為什么不能在std::copy()
等通用算法中使用它們而不是使用back_insert_iterator
,兩者之間有什么區別?
std::back_insert_iterator
是一種特定的輸出迭代器,它支持push_back
操作。 當您使用operator=
寫入它時,它會將值push_backs到底層容器中 - 因此,從這個意義上說,它充當具有push_back
成員函數的容器的適配器。
一個例子很容易理解:
std::vector<int> v;
std::back_insert_iterator<std::vector<int>> it(v);
*it = 10; // it is equivalent to v.push_back(10);
it = 99; // it is ALSO equivalent to v.push_back(99);
for (auto const & i : v)
std::cout << i << " " ; //10 99
它輸出:
10 99
在線演示 。
通常的迭代器操作++
和*
it
沒有影響。
但是你很少直接使用它們(我從未直接使用它直到現在)。 您可以將它們與算法一起使用,例如std::copy
在這種情況下,您還可以使用std::back_inserter
函數返回std::back_insert_iterator
類型的對象。
//assuming dest is a container which supports push_back!
std::copy(src.begin(), src.end(), std::back_inserter(dest));
您還希望看到以下(適配器)迭代器:
push_front
操作 insert
操作。 因此,根據容器,您選擇適配器迭代器。
請注意,它們都是輸出迭代器。
為什么不能在std :: copy()等通用算法中使用它們而不是使用back_insert_iterator。
當然,您可以在std::copy
等算法中使用隨機訪問迭代器(或任何輸出迭代器)作為第三個參數,但是假設迭代器引用現有范圍 - *it
和++it
是明確定義的你傳遞的價值。 您傳遞它們以覆蓋范圍的現有元素,而std::back_insert_iterator
將新元素添加到容器中。
希望有所幫助。
實際上,你可以在std::copy
完全使用常規迭代器。
int main() {
std::vector<int> vec{1, 2, 3, 4};
std::list<int> list{vec.size()};
std::copy(vec.begin(), vec.end(), list.begin());
// list = 1, 2, 3, 4
}
但是,正如您可能注意到的,這意味着:
len(source range)
默認元素 這是非常低效的,並且要求元素可以默認構造然后分配給。
相反, back_insert_iterator
是一個偽迭代器,它作為普通容器上的適配器運行。 如果你看一下界面,你會發現它根本不像常規迭代器那樣,只要你試圖推送一個項目,就會在它嵌入的底層容器引用上調用push_back
。
int main() {
std::list<int> list;
std::back_insert_iterator<std::list<int>> bii(list);
bii = 1;
bii = 2;
bii = 3;
bii = 4;
// list = 1, 2, 3, 4
// note: decltype(*bii) == bii&, so deferencing bii serves no purpose;
// similarly, ++bi does nothing either; both operations are just defined
// to mimick a regular operator interface so it can be used in regular
// algorithms over iterators.
}
因此,這兩種方法同樣有效,但具有不同的行為:
back_insert_iterator
允許您追加到現有容器 語義是不同的,選擇對手頭的任務有意義。
常規迭代器對它們正在使用的容器一無所知,除了它所持有的數據類型。 為了向容器添加元素,讓我們說一個向量,需要知道向量中的元素數量。
常規迭代器不會更改序列的大小或結構。 特別是隨機訪問迭代器只訪問特定位置的元素。
std::back_insert_iterator<Cont>
是一個trmplate,它建模一個具體的輸出迭代器,改變它所引用的每個元素所引用的序列:它為每個寫入的元素調用cont.push_back()
。 由於迭代器不會讀取它正在修改的序列,因此添加元素的效果非常好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.