Академический Документы
Профессиональный Документы
Культура Документы
Introduction
This documents the exception-handling behavior of the Standard Template Library available at
<http://www.ipmce.su/~fbp/stl/>, which is an adaptation of the work done at Silicon Graphics by Matt
Austern. Although this document is not intended as a proposal in itself, I hope that it illustrates the intent of a
proposal that Greg Colvin and I plan to submit for the London meeting. Our proposal will be substantially
similar in effect, but because of the realities of the way the standard is written we expect this document to be
more explicit and easier to understand.
Additionally:
Algorithms which operate on ranges of objects leave only fully-constructed objects in those ranges if
they terminate due to an exception.
Containers continue to fulfill all of their requirements, even after an exception occurs during a
mutating function. For example, a map will never give an inaccurate report of its size, or fail to meet
its performance requirements because the tree that implements it has become unbalanced.
A stronger guarantee is available for some operations: that if the operation terminates due to an
exception, program state will remain unchanged . For example, vector<T,A>::push_back() leaves
the vector unchanged if an exception is thrown, provided the library client fulfills the basic
requirements below. For some operations, the "strong guarantee" is available if additional
requirements are filled.
Page: 1
The following operations must return normally - they are forbidden to terminate due to an
exception:
Destructors of any classes used by the library. This includes all classes used as library template
parameters. It also includes all classes which fulfill "type requirements" of classes used as library
templates- an allocator's size_type, for example.
Valid uses of any of the required functionality of the following types. Note that invalid uses (e.g.
comparison of two iterators from different containers) are not prohibited from throwing an exception.
Presumably, invalid uses would cause worse problems than resource leaks:
The ForwardIterator arguments to the following:
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result)
uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x)
uninitialized_fill_n(ForwardIterator first, Size n, const T& x)
destroy(ForwardIterator first, ForwardIterator last)
An allocator's deallocate() function
Any of the required allocator types:
pointer
const_pointer
reference
const_reference
size_type
difference_type
Note: Algorithms like copy() expect that they are copying into real objects. The use of
raw_storage_iterator with most algorithms is inherently exception-unsafe:
Furthermore, there is no way to properly recover from this using an enclosing try/catch block, because
raw_storage_iterator has no function in its public interface to tell you how far it has been advanced.
Fortunately, many mutating operations give the strong guarantee with no additional requirements on the client.
To get the strong guarantee for others, you can either use the above technique or conform to some additional
requirements.
Page: 2
Operations that give the "strong guarantee" with no additional
requirements
( Operations labelled with * are guaranteed to return normallyif all basic requirements have been met)
uninitialized_fill()
uninitialized_copy()
uninitialized_fill_n()
deque<T,A> member functions:
swap(deque<T,A>&) *
push_back(const T&)
pop_back() *
push_front(const T&)
pop_front() *
list<T,A> member functions:
insert(iterator position, const T& x = T())
insert(iterator position)
push_back(const T&)
pop_back() *
push_front(const T&)
pop_front() *
splice(iterator position, list<T,Allocator>& x) *
splice(iterator position, list<T,Allocator>& x, iterator i) *
splice(iterator position, list<T,Allocator>& x, iterator first, iterator
last) *
swap(list<T,A>&) *
reverse() *
erase(iterator position) *
erase(iterator first, iterator last) *
vector<T, A> member functions:
reserve(size_type n)
swap(vector<T,A>&) *
push_back(const T&)
pop_back() *
bit_vector<A> member functions:
reserve(size_type n)
swap(bit_vector&) *
push_back(const T&)
pop_back() *
insert(iterator position, bool x = bool())
insert(iterator position)
insert(iterator position, const_iterator first, const_iterator last)
insert(iterator position, const bool* first, const bool* last)
insert(iterator position, size_type n, bool x)
erase(iterator position) *
erase(iterator first, iterator last) *
map<K, T, C, A> member functions:
operator[](const key_type& k)
insert(iterator position, const value_type& x)
insert(const value_type& x)
erase(const key_type& x) *
erase(iterator position) *
Page: 3
erase(iterator first, iterator last) *
set<K, C, A> member functions:
insert(iterator position, const value_type& x)
insert(const value_type& x)
erase(const key_type& x) *
erase(iterator position) *
erase(iterator first, iterator last) *
multimap<K, T, C, A> member functions:
insert(iterator position, const value_type& x)
insert(const value_type& x)
erase(const key_type& x) *
erase(iterator position) *
erase(iterator first, iterator last) *
multiset<K, C, A> member functions:
insert(iterator position, const value_type& x)
insert(const value_type& x)
erase(const key_type& x) *
erase(iterator position) *
erase(iterator first, iterator last) *
hash_map<K, T, H, E, A> member functions:
insert_noresize(const value_type& obj)
erase(const key_type& key) *
erase(iterator position) *
erase(iterator first, iterator last) *
hash_multimap<K, T, H, E, A> member functions:
insert_noresize(const value_type& obj)
erase(const key_type& key) *
erase(iterator position) *
erase(iterator first, iterator last) *
hash_set<T, H, E, A> member functions:
insert_noresize(const value_type& obj)
erase(const key_type& key) *
erase(iterator position) *
erase(iterator first, iterator last) *
hash_multiset<T, H, E, A> member functions:
insert_noresize(const value_type& obj)
erase(const key_type& key) *
erase(iterator position) *
erase(iterator first, iterator last) *
clear() for all containers *
all container const member functions *
all constructors, by language definition (included for completeness)
Page: 4
Term Meaning, when applied to a type T
( x and y of type T )
Function Requirements
Function Requirements
Page: 5
Function Requirements
position == end() - 1
erase(iterator position) OR T guaranteed copyable
last == end()
erase(iterator first, iterator last) OR T guaranteed copyable
resize(size_type new_size, const T& x) new_size == size() + 1
resize(size_type new_size) OR T guaranteed copyable
OR new_size <= size() *
Function Requirements
Page: 6
Function Requirements
Function Requirements
Function Requirements
Function Requirements
Page: 7