allocator.construct循环是否等于std :: uninitialized_copy?

时间:2011-05-18 16:18:44

标签: c++ stl allocator

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

allocator.allocate(n)获得了一大块内存。我还有conT个对象的容器(例如,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);
}

2 个答案:

答案 0 :(得分:6)

根据this explanations他们应该这样做,因为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);

所以我认为这并没有为他们留下任何不同的行为空间。所以回答你的问题:是的,确实如此。

答案 1 :(得分:0)

C ++ Primer 5th §13.6.2:

.....
uninitialized_copy在输入中的每个元素上调用construct 将该元素“复制”到目标位置的顺序。该算法 使用迭代器取消引用运算符从中获取元素 输入序列。因为我们传递了移动迭代器,所以取消引用 运算符产生右值引用,这意味着construct将使用 用于构造元素的move构造函数。
.....