在此上下文中,T
是某种类型,allocator
是该类型的分配器对象。默认情况下它是std::allocator<T>
,但这不一定是真的。
allocator.allocate(n)
获得了一大块内存。我还有con
个T
个对象的容器(例如,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);
}
答案 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构造函数。
.....