读书人

发现 visual studio 的联系关系容器不

发布时间: 2013-03-17 13:48:31 作者: rapoo

发现 visual studio 的关联容器不符合 C++ 标准
C++ 标准:关联容器 erase 返回 void,删除后原来迭代器不会失效

visual studio:关联容器 erase 返回删除元素下一个位置的迭代器,删除后原来的迭代器失效

是不是MS为了代码效率才这样做的,其他编译器是什么情况? 这样代码跨平台就有麻烦了。

[解决办法]
VC不符合C++标准是再正常不过了,建议放弃VC自带的。
SGI STL不但在效率上一直名列前茅,而且完全依照ISO C++之规范设计,使用者尽可放心。此外,SGI STL做到了thread-safe, 还体贴地为用户增设数种组件,如hash, hash_map,hash_multimap, slist和rope容器等等。因此无论在学习或实用中,SGI STL应是首选。无奈,SGI STL本质上是为了配合SGI自作的UNIX变体IRIX所量身定做,其它平台上的C++编译器想使用SGI STL,都需要一番周折。
好在英雄总能及时出现,俄国人Boris Fomitchev注意到这个问题之後,建立了一个free的项目,称为STLport(http://www.stlport.org/),旨在将SGI STL的基本代码移植到各种主流编译环境中,使各种编译器的用户都能够享受到SGI STL带来的先进之处。
[解决办法]
public member function
std::vector::erase<vector> iterator erase (iterator position);
iterator erase (iterator first, iterator last);
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
Erase elements
Removes from the vector either a single element (position) or a range of elements ([first,last)).

This effectively reduces the container size by the number of elements removed, calling their destructors.

Because vectors use an array as their underlying storage, erasing elements in positions other than the vector end causes the container to move all the elements after the segment erased to their new positions. This is generally an inefficient operation compared to the one performed for the same operation by other kinds of sequence containers (such as list or forward_list).


Parameters
position
Iterator pointing to a single element to be removed from the vector.
Member types iterator and const_iterator are random access iterator types that point to elements.
first, last
Iterators specifying a range within the vector] to be removed: [first,last). i.e., the range includes all the elements between first and last, including the element pointed by first but not the one pointed by last.
Member types iterator and const_iterator are random access iterator types that point to elements.


Return value
An iterator pointing to the new location of the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence.

Member type iterator is a random access iterator type that points to elements.


Example
123456789101112131415161718192021222324 // erasing from vector
#include <iostream>
#include <vector>



int main ()
{
std::vector<int> myvector;

// set some values (from 1 to 10)
for (int i=1; i<=10; i++) myvector.push_back(i);

// erase the 6th element
myvector.erase (myvector.begin()+5);

// erase the first 3 elements:
myvector.erase (myvector.begin(),myvector.begin()+3);

std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); ++i)
std::cout << ' ' << myvector[i];
std::cout << '\n';

return 0;
}


Output:

myvector contains: 4 5 7 8 9 10




Complexity
Linear on the number of elements erased (destructors) plus the number of elements after the last element deleted (moving).


Iterator validity
Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) guaranteed to keep referring to the same elements they were referring to before the call.


Data races
The container is modified.
None of the elements before position (or first) is accessed, and concurrently accessing or modifying them is safe.


See also
vector::pop_backDelete last element (public member function )vector::insertInsert elements (public member function )
[解决办法]
删除一个iterator,

其他iterator
仍然有效。
[解决办法]
ISO/IEC 14882:1998(E)
void erase(iterator position);
size_type erase(const key_type& x);
void erase(iterator first, iterator last);


ISO/IEC 14882:2011(E)
iterator erase(const_iterator position);
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);

VS是符合C++标准的。

读书人网 >C++

热点推荐