插入迭代器inserter在copy函數的運行機制是什麼?
list&
list&lst={1,2,3,4}; lst2, lst3;copy(lst.cbegin(),lst.cend(),front_inserter(lst2));//lst2包含 4 3 2 1 copy(lst.cbegin(),lst.cend(),inserter(lst3,lst3.begin()));//lst3包含 1 2 3 4
inserter會調用lst3.insert(),這裡lst3應該是先把第一個元素拷貝進去,然後它就成為了首元素,再插入應該會插入首元素之前啊,也就是lst3應該也是4 3 2 1,但是結果是1 2 3 4啊啊我明白了,inserter會返回一個迭代器,這個迭代器指向的並不是剛插入的元素,插入元素之後的那個元素,這樣就可以繼續迭代了~
我認為front_inserter / inserter的意思應該是push_front和push_back。
這是copy的源碼:
template&
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
while (first!=last) {
*result = *first;
++resu< ++first;
}
return resu<
}
insert_iterator&
{ iter=container-&>insert(iter,std::move(value)); ++iter; return *this; }
insert_iterator&
{ return *this; }
insert_iterator&
{ return *this; }
copy(lst.cbegin(),lst.cend(),inserter(lst3,lst3.begin()));
相當於:
first = lst.cbegin();
last = lst.cend();
result = inserter(lst3,lst3.begin());
while (first!=last) {
*result = *first;
++resu<
++first;
}
*result = *first;
這一行會使用到operator* 這個「*」重載操作符,返回的是*this。並且會使用到operator = 這個「=」的重載操作符。
這個「=」的操作符會通過list容器的iterator insert (const_iterator position, const value_type val)成員函數插入元素的值,並將新的待插入的位置賦值給iter(也就是相當於接下來的元素可以插入的位置,是list中剛才插入的元素的下一個位置),返回值就是An iterator that points to the first of the newly inserted elements.所以其實就是如輪子哥所說,一直在「push_back」。C++ Primer 5th,p358對這個問題有較詳細解釋.
書上有句:元素將被插入到給定迭代器所表示的元素之前(這句話很會被誤解)
我的理解是inserter將元素分成容器本身(舊元素)存在的元素和新插入的元素,比如插入1後,再插入2,分為新插入的元素1和本身存在的元素(也就是空),此時copy(lst.cbegin(),lst.cend(),inserter(lst3,lst3.begin()));這裡的lst3.begin()是指向舊元素的迭代器,所以就是1 2而不是2 1。
按輪子哥的理解就更加簡單明了。不知道我的理解是否有誤 @vczh ?
inserter(lst3,lst3.begin())
用lst3.begin()初始化了inserter,然後添加了之後。
inserter還是那個inserterbegin已不是那個begininserter的工作過程寫的很清楚啊,先調用insert()函數,再遞增insert()返回的迭代器。這導致inserter迭代器永遠指向初始給的那個元素。 代碼中lst3.begin()只是用來初始化inserter的,不是每次插入都重新初始化一次。你可以寫一個auto iter = lst3.begin(),然後把copy中的lst3.begin()換成iter,這樣好理解
去看文檔啊,寫的清清楚楚呢~
以下引用自sherlly666的博客:
除了普通迭代器,C++標準模板庫還定義了幾種特殊的迭代器,分別是插入迭代器、流迭代器、反向迭代器和移動迭代器,定義在&
首先,什麼是插入迭代器?插入迭代器是指被綁定在一個容器上,可用來向容器插入元素的迭代器。
back_inserter:創建一個使用push_back的迭代器。
inserter:此函數接受第二個參數,這個參數必須是一個指向給定容器的迭代器。元素將被插入到給定迭代器所表示的元素之前。
front_inserter:創建一個使用push_front的迭代器(元素總是插入到容器第一個元素之前)。
list&
list&
copy(lst.cbegin(), lst.cend(), back_inserter(lst2));
//lst2包含10,1,2,3,4,5,6,7,8,9
copy(lst.cbegin(), lst.cend(), inserter(lst3, lst3.begin()));
//lst3包含1,2,3,4,5,6,7,8,9,10
copy(lst.cbegin(), lst.cend(), front_inserter(lst4));
//lst4包含9,8,7,6,5,4,3,2,1,10
推薦閱讀:
※在C#中,如何實現跟native dll 中途的線程間通信?
※編程中你們都習慣怎麼使用大括弧?
※如何解決光線跟蹤中浮點數誤差導致的渲染錯誤?
※既然建議盡量避免使用goto語句為何C++還要支持goto呢?
※主推 iOS 但是考慮跨平台,可否跳過 Objective-C 而直接學 C++ 和 Cocos2d-X 呢?