我想一個一個地洗掉串列元素。在洗掉任何串列元素之前,我想查看整個串列。
#include <iostream>
#include <list>
int main()
{
std::list<int>numbers{0,1,2,3,4,5,6,7,8,9};
auto it=numbers.begin();
for(int i=0;i<10;i ){
for(auto j:numbers)
std::cout<<j<<" ";
std::cout<<std::endl;
it=numbers.erase(it);
it ;
}
return 0;
}
輸出:
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 3 4 5 6 7 8 9
1 3 5 6 7 8 9
1 3 5 7 8 9
1 3 5 7 9
double free or corruption (out)
為什么這個程序只涉及一半的元素。如何一步一步洗掉所有串列元素?我知道我可以使用numbers.clear(),但我不需要。
另外,為什么擦除不按順序進行?(洗掉 0,然后洗掉 2,然后洗掉 4)?
uj5u.com熱心網友回復:
問題在于這兩行
it=numbers.erase(it);
it ;
函式 ,list::erase回傳一個迭代器,指向最后一個被擦除元素之后的元素。在這里,您的代碼從串列中洗掉該專案并設定it為串列中的下一個元素。然后指令it 將迭代器再前進一位,從而跳過串列中的一項。
簡單的解決方案是注釋掉該it 行:
#include <iostream>
#include <list>
int main()
{
std::list<int>numbers{0,1,2,3,4,5,6,7,8,9};
auto it=numbers.begin();
for(int i=0;i<10;i )
{
for(auto j:numbers)
std::cout<<j<<" ";
std::cout<<std::endl;
it=numbers.erase(it);
//it ;
}
return 0;
}
這給出了這個輸出:
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9
4 5 6 7 8 9
5 6 7 8 9
6 7 8 9
7 8 9
8 9
9
uj5u.com熱心網友回復:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
template <typename Container>
void print(const Container& container, std::ostream& sout = std::cout) {
std::copy(std::begin(container), std::end(container),
std::ostream_iterator<typename Container::value_type>(sout, " "));
sout << '\n';
}
int main() {
std::list<int> numbers{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// Note that the update action is skipped
for (auto it = numbers.begin(); it != numbers.end();) {
print(numbers);
it = numbers.erase(it);
}
return 0;
}
這可以通過迭代器專門完成。我將列印移到了它自己的功能中。這里的關鍵是回圈宣告不再負責更新迭??代器,因為它現在發生在主體中。閱讀 aboutstd::list<T>::erase()告訴我們該函式回傳一個迭代器,該迭代器指向擦除后的元素。由于我們從頭開始擦除,因此擦除行為自然會在整個串列中移動。
同樣重要的是要注意回圈必須以這種方式完成。從串列中擦除會使串列中所有預先存在的迭代器失效。現在唯一有效的是由 erase() 函式回傳的迭代器。
uj5u.com熱心網友回復:
it=numbers.erase(it);
it ;
在第一行中,串列洗掉了迭代器指向的元素并回傳一個指向下一個元素的迭代器。舊元素不再存在,it傳遞的元素erase()變得無效。這就是為什么你必須使用回傳的迭代器,它指向下一個元素。
然后第二行跳過它并且迭代器不再指向新串列的開頭。
您正在從串列中洗掉每個第二個元素:擦除,跳過,擦除,跳過,擦除,跳過,...
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/477975.html
上一篇:如何使用sscanf決議浮點數
