簡體   English   中英

std :: sets上std :: advance的問題

[英]issue with std::advance on std::sets

我偶然發現了stl算法中的錯誤。

當我將迭代器推進到容器的末尾時,得到的結果不一致。 有時我得到container.end(),有時我得到最后一個元素。 我用以下代碼說明了這一點:

#include <algorithm>
#include <cstdio>
#include <set>

using namespace std;
typedef set<int> tMap;

int main(int argc, char** argv)
{
    tMap::iterator i;
    tMap the_map;

    for (int i=0; i<10; i++)
        the_map.insert(i);

#if EXPERIMENT==1
    i = the_map.begin();
#elif EXPERIMENT==2
    i = the_map.find(4);
#elif EXPERIMENT==3
    i = the_map.find(5);
#elif EXPERIMENT==4
    i = the_map.find(6);
#elif EXPERIMENT==5
    i = the_map.find(9);
#elif EXPERIMENT==6
    i = the_map.find(2000);
#else
    i = the_map.end();
#endif

    advance(i, 100);

    if (i == the_map.end())
        printf("the end\n");
    else
        printf("wuh? %d\n", *i);

    return 0;
}

在實驗3和5中,我得到了以下意外的(根據我)行為,在其中我得到了最后一個元素而不是the_map.end()。

[tim@saturn advance]$ uname -srvmpio
Linux 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:37:32 EDT 2006 i686 athlon i386 GNU/Linux
[tim@saturn advance]$ g++ --version
g++ (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[tim@saturn advance]$ g++ -DEXPERIMENT=1 advance.cc
[tim@saturn advance]$ ./a.out
the end
[tim@saturn advance]$ g++ -DEXPERIMENT=2 advance.cc
[tim@saturn advance]$ ./a.out
the end
[tim@saturn advance]$ g++ -DEXPERIMENT=3 advance.cc
[tim@saturn advance]$ ./a.out
wuh? 9
[tim@saturn advance]$ g++ -DEXPERIMENT=4 advance.cc
[tim@saturn advance]$ ./a.out
the end
[tim@saturn advance]$ g++ -DEXPERIMENT=5 advance.cc
[tim@saturn advance]$ ./a.out
wuh? 9
[tim@saturn advance]$ g++ -DEXPERIMENT=6 advance.cc
[tim@saturn advance]$ ./a.out
the end
[tim@saturn advance]$ g++ -DEXPERIMENT=7 advance.cc
[tim@saturn advance]$ ./a.out
the end
[tim@saturn advance]$

在sgi網站上(請參見頂部的鏈接),它具有以下示例:

list<int> L;
L.push_back(0);
L.push_back(1);

list<int>::iterator i = L.begin();
advance(i, 2);
assert(i == L.end());

我認為斷言應適用於其他容器類型,不是嗎?

我想念什么?

謝謝!

STL高級算法中沒有錯誤。

如果您超過集合的末尾會發生什么,這是不確定的。

未定義行為是C / C ++中的一個常見概念,結果始終對未定義行為有效,因為...它是未定義行為。

如果您執行某些操作會帶來不確定的行為,則可能會在程序中出現錯誤。

您正在將迭代器推進到容器的末尾。 從文檔中:

如果n> 0,則等效於執行++

容器中沒有100個元素,但您將迭代器的位置提高了100個。 當它碰到容器的末端時,它不會停止,因為它不知道容器的末端在哪里。

當我將迭代器移出容器的末端時,...

...您得到不確定的行為 然后,無論發生什么情況,根據C ++標准都可以。 這可能比不一致的結果要糟糕得多。

您缺少的是在示例中,列表僅包含兩個元素。 如果您從兩個項目的清單的開頭前進2個步驟,則應該位於清單的結尾。 這就是該示例所斷言的。

如果您要前進兩個以上的步驟,那么您將處在未定義的行為范圍內,並且斷言不再有意義。

暫無
暫無

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

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