8

このコンテキストでTは、特定のタイプでありallocator、そのタイプのアロケータオブジェクトです。デフォルトではそうですstd::allocator<T>が、これは必ずしも正しいとは限りません。

によって取得されたメモリのチャンクがありますallocator.allocate(n)。オブジェクトのコンテナもconありTます(たとえば、std::vector<T>)。Tそのメモリのチャンクをオブジェクトで初期化したい。

メモリのチャンクの場所はに保存されT* dataます。

これらの2つのコード例は常に同じですか?

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

そして、これらの2つについては?

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

2 に答える 2

6

この説明によるとallocator::construct、オブジェクトを構築し、オブジェクトを構築すると言われているように、彼らは同じことをする必要がありstd::uninitialized...ます。しかし、私は、あなた自身を実装するときに、標準が正確に何を言っているのか、そしてあなたがどのような自由を持っているのかを知りませんallocator::construct

編集:わかりました。C++ 03標準はセクション20.1.5§2表32に記載されており、 (標準に準拠したアロケータだけでなく)construct(p,t)と同じ効果があります。そして20.4.4.1§1では、それはと同じ効果を持つはずですnew ((void*)p) T(t)std::allocatoruninitialized_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);

ですから、それは彼らが異なった振る舞いをする余地を残さないと思います。だからあなたの質問に答えるために:はい、そうです。

于 2011-05-18T16:34:14.967 に答える
0

C ++入門書5th§13.6.2:

.....入力シーケンスの各要素を
uninitialized_copy呼び出しconstructて、その要素を宛先に「コピー」します。このアルゴリズムは、イテレーター逆参照演算子を使用して、入力シーケンスから要素をフェッチします。移動イテレーターを渡したため、間接参照演算子は右辺値参照を生成します。これはconstruct、移動コンストラクターを使用して要素を構築することを意味します。
....。

于 2020-04-20T13:00:07.743 に答える