簡體   English   中英

g ++的std :: list :: sort是否會使迭代器無效?

[英]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),包括mergesort的部分的開頭說:“列表允許從列表的中間快速插入和擦除,專門為其提供了某些操作”(23.3.5.5/1)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM