分配器构造循环是否等于 std::uninitialized_copy

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

本文关键字:std uninitialized copy 循环 是否 分配器      更新时间:2023-10-16

在此上下文中,T是某种类型,allocator是该类型的分配器对象。默认情况下,它是std::allocator<T>但这不一定是真的。

我有一大块内存被allocator.allocate(n).我还有一个T对象的容器con(例如,一个std::vector<T>)。我想用T对象初始化该内存块。

内存块的位置存储在 T* data 中。

这两个代码示例是否始终相同?

#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);
}

而对于这两个?

#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);
}

根据这个解释,他们应该做同样的事情,因为据说allocator::construct构造对象,std::uninitialized...构造对象。但我不知道,在实施自己的allocator::construct时,标准到底说了什么,你有什么自由.

编辑:好的,C++03标准在第20.1.5节§2表32中指出,construct(p,t)应具有与new ((void*)p) T(t)相同的效果(对于任何符合标准的分配器,而不仅仅是std::allocator)。在 20.4.4.1 §1 中,该uninitialized_copy应具有与

for (; first != last; ++result, ++first)
    new (static_cast<void*>(&*result))
            typename iterator_traits<ForwardIterator>::value_type(*first);

在 20.4.4.2 §1 中,该uninitialized_fill具有

for (; first != last; ++first)
    new (static_cast<void*>(&*first))
            typename iterator_traits<ForwardIterator>::value_type(x);

所以我认为这不会给他们留下任何不同行为的余地。所以要回答你的问题:是的,确实如此。

C++ 入门 5th §13.6.2:

.....
uninitialized_copy对输入中的每个元素进行construct调用 序列以将该元素"复制"到目标中。该算法 使用迭代器取消引用运算符从 输入序列。因为我们传递了移动迭代器,所以取消引用 运算符生成右值引用,这意味着construct将使用 用于构造元素的移动构造函数。
.....