《從缺陷中學習C/C++》第3章庫函數問題,本章主要介紹庫函數的使用中會遇到的問題。使用庫函數可以降低軟件開發的難度,提高代碼編寫的效率。本節為大家介紹multiset容器erase函數的誤用。
3.16 multiset容器erase函數的誤用
代碼示例
- int main(){
- multiset <int> c1;
- c1.insert(3);
- c1.insert(2);
- c1.insert(3);
- c1.insert(3);
- c1.insert(5);
- int x=3;
- c1.erase(x);//remove one element with value 3
- for(multiset <int>::iterator it = c1.begin(); it != c1.end(); it++)
- {
- cout << *it << endl;
- }
- return 0;
- }
現象&后果
代碼期望刪除一個值為3的元素,但實際運行結果顯示刪除了所有值為3的元素。
Bug分析
multiset帶一個參數的erase函數原型有兩種。一是傳遞一個元素值,如上面例子代碼中,這時候刪除的是集合中所有值等於輸入值的元素,並且返回刪除的元素個數;另外一種是傳遞一個指向某個元素的iterator,這時候刪除的就是這個對應的元素,無返回值。用戶需要根據自己的應用場景,正確調用對應的原型。例子代碼中本意是想刪除一個元素,但實際上是刪除了所有值為3的元素,不符合預期。
正確代碼
- int main(){
- multiset <int> c1;
- c1.insert(3);
- c1.insert(2);
- c1.insert(3);
- c1.insert(3);
- c1.insert(5);
- int x=3;
- multiset <int>::iterator pos = c1.find(x);
- c1.erase(pos);//remove one element with value 3
- for(multiset <int>::iterator it = c1.begin(); it != c1.end(); it++)
- {
- cout << *it << endl;
- }
- return 0;
- }
編程建議
在使用multiset的時候,需要注意mutilset與普通set容器的主要區別,即multiset允許元素重復,set不允許元素重復。這會給一些操作帶來不同的影響。