In this context T
is a certain type and allocator
is an allocator object for that type. By default it is std::allocator<T>
but this is not necessarily true.
I have a chunk of memory acquired by allocator.allocate(n)
. I also have a container con
of T
objects (say, a std::vector<T>
). I want to initialize that chunk of memory with the T
object(s).
The location of the chunk of memory is stored in T* data
.
Are these two code examples always identical?
#include <memory>
// example 1
std::uninitialized_copy(con.begin(), con.end(), data)
// example 2
std::vector<T>::const_iterator in = con.begin();
for (T* out = data; in != con.end(); ++out, ++in) {
allocator.construct(out, *in);
}
And for these two?
#include <memory>
T val = T(); // could be any T value
// example 3
std::uninitialized_fill(data, data + n, val)
// example 4
for (T* out = data; out != (data + n); ++out) {
allocator.construct(out, val);
}
According to this explanations They should do the same, as allocator::construct
is said to construct the object and std::uninitialized...
also constructs the objects. But I do not know, what exactly the standard says and what freedom you have, when implementing your own allocator::construct
.
EDIT: Ok, the C++03 standard states in section 20.1.5 §2 table 32, that construct(p,t)
should have the same effect as new ((void*)p) T(t)
(for any standard compliant allocator, not only std::allocator
). And in 20.4.4.1 §1, that uninitialized_copy
should have the same effect as
for (; first != last; ++result, ++first)
new (static_cast<void*>(&*result))
typename iterator_traits<ForwardIterator>::value_type(*first);
and in 20.4.4.2 §1, that uninitialized_fill
has an effect of
for (; first != last; ++first)
new (static_cast<void*>(&*first))
typename iterator_traits<ForwardIterator>::value_type(x);
So I think that doesn't leave any room for them to behave differently. So to answer your question: yes, it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With