2013-03-11 42 views
0

假設我們有這段代碼:set :: erase()如何爲set :: end作爲參數運行?

set<int> s; 
set<int>::iterator it = s.find(val); 
s.erase(it); 

正如cplusplus.com說,如果int valset<int> s存在,那麼,s.find(val)將返回set::end

現在我的問題是,如果我們通過set::endset::erase()將會發生什麼?

是否可以接收segmentation faultaborted等信號並獲取運行時錯誤?或者這個特例在set處理?

+0

我相信這是不確定的,你不知道會發生什麼,它甚至可以在相同的運行做不同的事情該程序。 – 2013-03-11 19:56:30

+2

爲什麼不讓你的代碼更簡單,只需使用:'s.erase(val);'(即使'val'不存在,它給出了定義的行爲)? – 2013-03-11 20:03:55

+0

_「如果指定了無效的位置或範圍,則會導致未定義的行爲。」_ [最後一行](http://www.cplusplus.com/reference/set/set/erase/)。 – deepmax 2013-03-11 20:05:20

回答

5

在C++ 03,的採用單個迭代器std::set::erase()的行爲在表69中定義,whihc具有以下假設(高亮加入):

在表69中,X是關聯容器類,a是X的值,a_uniq是X支持唯一鍵時X的值,而a當X支持多個鍵時,a和e是X的值,i和j滿足輸入迭代器要求並引用value_type的元素, [I,J)是一個有效的範圍,p是一個有效的迭代到,q是一個有效的提領迭代到,[Q1,Q2)處於有效範圍,t爲X的值:: VALUE_TYPE ,k是X :: key_type的值,c是typ的值e X :: key_compare。

表69說,這個關於erase()功能:

a.erase(q) - 擦除指向的元素q

換句話說,迭代器必須提領。如果它不是未定義的行爲,因爲前提條件不被保留。

對圖書館的行爲並沒有任何特別的承諾。某些庫(如MSVC)可以在某些配置中包含迭代器調試。例如,在VS 2012與調試配置中運行時,你會看到以下內容:

--------------------------- 
Microsoft Visual C++ Runtime Library 
--------------------------- 
Debug Assertion Failed! 

Program: C:\Windows\system32\MSVCP110D.dll 
File: c:\program files (x86)\microsoft visual studio 11.0\vc\include\xtree 
Line: 1326 

Expression: map/set erase iterator outside range 

For information on how your program can cause an assertion 
failure, see the Visual C++ documentation on asserts. 

(Press Retry to debug the application) 

--------------------------- 
Abort Retry Ignore 
--------------------------- 
4

這是未定義的行爲。即它可能什麼也不做,程序崩潰等等。不要這樣做,即使你的stdlib實現「工作正常」。

+1

事實上它是未定義的,但你應該鏈接到一些文檔:http://www.cplusplus.com/reference/set/set/erase/#exceptions – 2013-03-11 19:58:45

2

對於關聯容器,erase定義如下:

a.erase(q)
返回類型:iterator
擦除元件通過q指向。在元素被擦除之前,返回指向緊跟在q之後的元素的迭代器。如果不存在這樣的元素,則返回a.end()

該功能僅根據q定義。 q被描述爲「有效的可解引用 常量迭代器到a」。過去的最終迭代器不可解引用,所以你會得到未定義的行爲。

是否可以接收信號,如分段故障或中止,並獲得運行時錯誤?

是的,這是可能的,但你不能保證會發生什麼。

+0

@AndyProwl哎呀,謝謝! – 2013-03-11 20:04:06