Re: No-fail guarantee for assignment to equally sized std::vector?
Niels Dekker - no return address schrieb:
Is there any commonly used STL implementation whose vector assignment
operator might fail, when both vectors have the same size, and their
elements are of a built-in type?
I have not seen one, but because there exists no guarantee,
I would not take this as a guide-line, there exists a simple
solution, v.i.
I can imagine that the assignment would be implemented by copy-and-swap:
template <typename T>
vector<T>& vector<T>::operator=(const vector& arg) {
vector temp = arg;
this->swap(temp);
return *this;
}
Would such an implementation be valid?
Yes, it would be.
Alberto wrote:
vector and deque are not strongly exception-safe (at least in
assignment), if assignment fails the state of v1 is not predictable.
Hmmm... Thanks! So I guess I'd rather use std::copy, instead of
operator=, when my vectors have the same size.
if (v1.size() == v2.size())
copy(v2.begin(), v2.end(), v1.begin()); // Fail-safe! :-)
else
v1 = v2;
No reason to use such a complicated code for such a
simple request. The most obvious solution fulfilling
your requirements is
v1.assign(v2.begin(), v2.end());
This cannot fail by implication for all POD types and for all
user-defined types, which have non-failing copy c'tors
and copy assignment ops (and d'tors, of course).
Reasoning: The standard says that the effect of this assign
overload is given by:
erase(begin(), end());
insert(begin(), first, last);
Further on it says for erase:
"The destructor of T is called the number of times equal
to the number of the elements erased, but the assignment
operator of T is called the number of times equal to the
number of elements in the vector after the erased elements."
and insert:
"Causes reallocation if the new size is greater than the
old capacity. If no reallocation happens, all the iterators
and references before the insertion point remain valid. If an
exception is thrown other than by the copy constructor or
assignment operator of T there are no effects."
and finally the reserve function guarantees:
"Reallocation invalidates all the references, pointers, and
iterators referring to the elements in the sequence. It is
guaranteed that no reallocation takes place during insertions
that happen after a call to reserve() until the time when an
insertion would make the size of the vector greater than the
size specified in the most recent call to reserve()."
The most recent draft has made the last sentence stricter:
"[..] until the time when an insertion would make the size of
the vector greater than the value of capacity()."
Mix this all together and you can conclude that under these
special constraints the assignment with assign will not
reallocate and it will not fail.
Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]