开发者

Does an allocator.construct loop equal std::uninitialized_copy?

开发者 https://www.devze.com 2023-03-06 15:42 出处:网络
In this context T isa certain type and allocator is an allocator object for that type. By default it is std::allocator<T> but this is not necessarily true.

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>

/开发者_StackOverflow/ 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.


C++ Primer 5th §13.6.2:

.....
uninitialized_copy calls construct on each element in the input sequence to “copy” that element into the destination. That algorithm uses the iterator dereference operator to fetch elements from the input sequence. Because we passed move iterators, the dereference operator yields an rvalue reference, which means construct will use the move constructor to construct the elements.
.....

0

精彩评论

暂无评论...
验证码 换一张
取 消