15

C ++では、上にC配列を使用する理由はほとんどありませんstd::vector。少なくともC++03では、これらのいくつかの説得力のある理由の1つは、初期化されていないオブジェクトの配列を割り当てるためにベクトルを使用することが不可能であるという事実でした。の「fill」コンストラクタstd::vectorは次のとおりです。

vector(size_type count, const T& value = T())

つまり...

int* array = new array[1000000];

以下よりもはるかに効率的である可能性があります。

std::vector<int> v(1000000);

...ベクトルコンストラクタは整数の配列をゼロで初期化する必要があるためです。したがって、PODのベクトルを操作する場合、malloc;に相当するものはありません。あなたが得ることができる最高のものはと同等callocです。

C ++ 11は、「値の初期化」の概念でこれを変更したようです。C ++ 11では、デフォルトの引数なしでstd::vector単一の値をとる新しいコンストラクターがあります。size_typeこれにより、ベクトル内のすべての要素が「値初期化」されます。C ++ 11標準は、「値の初期化」と「ゼロの初期化」を区別します。

私の理解では、「値の初期化」は、でデフォルトのコンストラクターを呼び出すことと同じですTTがのようなPODタイプの場合int、デフォルトのコンストラクタは初期化されていない整数を作成するだけです。したがって、C ++ 11では、がPODである場合explicit vector::vector(size_type count)と真に同等です。mallocT

ただし、これについての私の理解は、最終的な標準ではなく、ドラフトC++11標準に基づいています。

質問:私の理解はここで正しいですか?がPODの場合explicit vector::vector(size_type count)、初期化されていない配列(と同様)を提供しますか?mallocT

4

2 に答える 2

22

質問:私の理解はここで正しいですか?がPODの場合explicit vector::vector(size_type count)、初期化されていない配列(と同様)を提供しますか?mallocT

いいえ。ここではC++03とC++11に違いがありますが、そうではありません。違いは、C ++ 03では、vector<T>(N)デフォルトでを作成しT、それをNコピーしてベクターに入力することです。

一方、C ++ 11では、vector<T>(N)デフォルトで構築T N時間がベクターに入力されます。PODタイプの場合、効果は同じです。実際、ほとんどすべてのタイプで効果は同じであると思います。unique_ptrただし、 (移動専用タイプ)のようなものの場合、違いは重要です。移動専用タイプのコピーを作成できないため、C++03セマンティクスは機能しません。

それで:

vector<unique_ptr<int>> v(10);

10個のnullunique_ptrs(相互のコピーではない)のベクトルを作成します。

まれに、違いが生じ、次の方法で簡単に実行できるC++03の動作が必要になる場合があります。

vector<T> v(10, T());
于 2013-02-26T19:58:43.943 に答える
9

注:値の初期化はアロケーターで行われるため、デフォルトで構築された要素の値の初期化ではなく、ベクトルでデフォルトの初期化を実行する場合は、次のように実行できます。

template<typename T>
struct DefaultInitAllocator {
    template<typename U>
    void construct(U* p)
    { ::new (static_cast<void*>(p)) U; }

    template<typename U, typename... Args>
    void construct(U* p, Args&&... args)
    { ::new (static_cast<void*>(p)) U(std::forward<Args>(args)...); }

    // ... rest of the allocator interface
};

// ...
typedef std::vector<int, DefaultInitAllocator<int>> DefaultInitVectorInt;
于 2013-02-27T18:36:19.340 に答える