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

发布于 2024-11-07 21:45:59 字数 877 浏览 0 评论 0原文

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

我有一块由 allocator.allocate(n) 获取的内存。我还有一个包含 T 对象的容器 con(例如,std::vector)。我想用 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);
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三人与歌 2024-11-14 21:45:59

根据 这个解释 他们应该做同样的事情,如 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);

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

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.

始终不够 2024-11-14 21:45:59

C++ 入门第 5 章 §13.6.2:

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

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.
.....

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文