![](/img/trans.png)
[英]std::list::erase does not invalidate other iterators and references
[英]Does g++'s std::list::sort invalidate iterators?
根據SGI,cplusplus.com以及我所獲得的所有其他來源,std :: list的sort()成員函數不應使迭代器無效。 但是,當我運行以下代碼(c ++ 11)時,情況似乎並非如此:
#include <list>
#include <chrono>
#include <random>
#include <iostream>
#include "print.hpp"
unsigned int seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine generator(seed);
std::uniform_int_distribution<unsigned int> distribution(1, 1000000000);
auto rng = std::bind(distribution, generator);
// C++11 RNG stuff. Basically, rng() now gives some unsigned int [1, 1000000000]
int main() {
unsigned int values(0);
std::cin >> values; // Determine the size of the list
std::list<unsigned int> c;
for (unsigned int n(0); n < values; ++n) {
c.push_front(rng());
}
auto c0(c);
auto it(c.begin()), it0(c0.begin());
for (unsigned int n(0); n < 7; ++n) {
++it; // Offset these iterators so I can print 7 values
++it0;
}
std::cout << "With seed: " << seed << "\n";
std::cout << "Unsorted list: \n";
print(c.begin(), c.end()) << "\n";
print(c.begin(), it) << "\n\n";
auto t0 = std::chrono::steady_clock::now();
c0.sort();
auto d0 = std::chrono::steady_clock::now() - t0;
std::cout << "Sorted list: \n";
print(c0.begin(), c0.end()) << "\n";
print(c0.begin(), it0) << "\n"; // My own print function, given further below
std::cout << "Seconds: " << std::chrono::duration<double>(d0).count() << std::endl;
return 0;
}
在print.hpp中:
#include <iostream>
template<class InputIterator>
std::ostream& print(InputIterator begin, const InputIterator& end,
std::ostream& out = std::cout) {
bool first(true);
out << "{";
for (; begin != end; ++begin) {
if (first) {
out << (*begin);
first = false;
} else {
out << ", " << (*begin);
}
}
out << "}";
return out;
}
樣本輸入/輸出:
11
With seed: 3454921017
Unsorted list:
{625860546, 672762972, 319409064, 8707580, 317964049, 762505303, 756270868, 249266563, 224065083, 843444019, 523600743}
{625860546, 672762972, 319409064, 8707580, 317964049, 762505303, 756270868}
Sorted list:
{8707580, 224065083, 249266563, 317964049, 319409064, 523600743, 625860546, 672762972, 756270868, 762505303, 843444019}
{8707580, 224065083}
Seconds: 2.7e-05
一切正常,除了打印。 它應該顯示7個元素,但是如果“ value”設置為大於7,則實際數字是相當隨意的。有時它什么都不給出,有時它給出1,有時10,有時7,等等。我的代碼有明顯的錯誤,還是表明g ++的std :: list(和std :: forward_list)不符合標准?
提前致謝!
迭代器保持有效,並且仍引用列表中已重新排序的相同元素。
因此,我認為您的代碼無法實現您認為的功能。 從列表的開始到列表排序后第7個元素結束的地方,它都會打印列表。 因此,它打印的元素數量取決於列表中的值。
考慮以下代碼:
#include <list>
#include <iostream>
int main() {
std::list<int> l;
l.push_back(1);
l.push_back(0);
std::cout << (void*)(&*l.begin()) << "\n";
l.sort();
std::cout << (void*)(&*l.begin()) << "\n";
}
所打印的兩個地址不同,表明(不同於std::sort
), std::list::sort
通過更改元素之間的鏈接進行排序,而不是通過為元素分配新值來進行排序。
我一直認為這是強制性的(對於reverse()
)。 我實際上找不到明確的說法,但是,如果您查看merge
的描述,並認為list::sort
存在的原因大概是因為mergesort與list配合得很好,那么我認為它“顯然”意。 merge
表示:“ x的移動元素的指針和引用現在引用的是相同元素,但它們是* this的成員”(23.3.5.5./23),包括merge
和sort
的部分的開頭說:“列表允許從列表的中間快速插入和擦除,專門為其提供了某些操作”(23.3.5.5/1)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.