Namespaces
Variants

std::vector<T,Allocator>:: reserve

From cppreference.net
void reserve ( size_type new_cap ) ;
(constexpr C++20以降)

ベクターの容量(再割り当てを必要とせずにベクターが保持できる要素の総数)を、 new_cap 以上の値に増加させます。 new_cap が現在の capacity() より大きい場合、新しいストレージが割り当てられます。それ以外の場合、この関数は何も行いません。

reserve() はベクトルのサイズを変更しません。

new_cap capacity() より大きい場合、すべてのイテレータ( end() イテレータを含む)および要素へのすべての参照は無効化されます。それ以外の場合、イテレータや参照は無効化されません。

reserve() の呼び出し後は、挿入操作によってベクターのサイズが capacity() の値を超える場合を除き、再割り当ては発生しません。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - HTMLタグ、属性、リンク先はすべて保持されています - C++関連の専門用語(Parameters、Return value、Exceptions、Complexity、Notes、Example、Defect reports、See also)は原文のまま保持されています - 数値や書式設定は変更していません

パラメータ

new_cap - ベクターの新しい容量(要素数)
型要件
-
T MoveInsertable の要件を満たさなければならない * this に対して。 (C++11以降)

戻り値

(なし)

例外

  • std::length_error がスローされる条件: new_cap > max_size ( ) の場合。
  • Allocator::allocate() によってスローされる例外(通常は std::bad_alloc )。

例外がスローされた場合、この関数は効果を持ちません( strong exception guarantee )。

T のムーブコンストラクタが noexcept でなく、かつTが *this CopyInsertable でない場合、vectorは例外を投げる可能性のあるムーブコンストラクタを使用する。例外が投げられた場合、保証は放棄され、効果は未規定となる。

(C++11以降)

計算量

コンテナの size() に対して最大で線形。

注記

正しく reserve() を使用することで不必要な再割り当てを防ぐことができますが、不適切な reserve() の使用(例えば、すべての push_back() 呼び出しの前に実行するなど)は、実際には再割り当ての回数を増加させ(容量が指数的ではなく線形的に増加する原因となる)、計算量の増加とパフォーマンスの低下を招く可能性があります。例えば、任意のベクターを参照で受け取り要素を追加する関数は、通常、ベクターの使用特性を知らないため、ベクターに対して reserve() 呼び出すべきではありません

範囲を挿入する際は、 reserve() に続く一連の push_back() とは異なり、適切なキャパシティ増加動作を維持するため、一般的に範囲バージョンの insert() を使用することが推奨されます。

reserve() はコンテナの容量を減らすために使用することはできません。その目的には shrink_to_fit() が提供されています。

#include <cstddef>
#include <iostream>
#include <new>
#include <vector>
// デバッグ出力付き最小限のC++11アロケータ
template<class Tp>
struct NAlloc
{
    typedef Tp value_type;
    NAlloc() = default;
    template<class T>
    NAlloc(const NAlloc<T>&) {}
    Tp* allocate(std::size_t n)
    {
        n *= sizeof(Tp);
        Tp* p = static_cast<Tp*>(::operator new(n));
        std::cout << "allocating " << n << " bytes @ " << p << '\n';
        return p;
    }
    void deallocate(Tp* p, std::size_t n)
    {
        std::cout << "deallocating " << n * sizeof *p << " bytes @ " << p << "\n\n";
        ::operator delete(p);
    }
};
template<class T, class U>
bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; }
template<class T, class U>
bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; }
int main()
{
    constexpr int max_elements = 32;
    std::cout << "using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        v1.reserve(max_elements); // 少なくとも max_elements * sizeof(int) バイトを確保
        for (int n = 0; n < max_elements; ++n)
            v1.push_back(n);
    }
    std::cout << "not using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        for (int n = 0; n < max_elements; ++n)
        {
            if (v1.size() == v1.capacity())
                std::cout << "size() == capacity() == " << v1.size() << '\n';
            v1.push_back(n);
        }
    }
}

出力例:

using reserve: 
allocating 128 bytes @ 0xa6f840
deallocating 128 bytes @ 0xa6f840
not using reserve: 
size() == capacity() == 0
allocating 4 bytes @ 0xa6f840
size() == capacity() == 1
allocating 8 bytes @ 0xa6f860
deallocating 4 bytes @ 0xa6f840
size() == capacity() == 2
allocating 16 bytes @ 0xa6f840
deallocating 8 bytes @ 0xa6f860
size() == capacity() == 4
allocating 32 bytes @ 0xa6f880
deallocating 16 bytes @ 0xa6f840
size() == capacity() == 8
allocating 64 bytes @ 0xa6f8b0
deallocating 32 bytes @ 0xa6f880
size() == capacity() == 16
allocating 128 bytes @ 0xa6f900
deallocating 64 bytes @ 0xa6f8b0
deallocating 128 bytes @ 0xa6f900

欠陥報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用バージョン 公開時の仕様 正しい仕様
LWG 329 C++98 挿入操作によってvectorのサイズが
直近の reserve() 呼び出しで指定された
サイズを超える場合に再割り当てが発生する可能性あり
vectorのサイズが
capacity() を超えた場合にのみ
発生する
LWG 2033 C++11 T MoveInsertable であることが要求されていなかった 要求される

関連項目

現在割り当てられているストレージに格納できる要素数を返す
(public member function)
格納可能な最大要素数を返す
(public member function)
格納されている要素数を変更する
(public member function)
未使用のメモリを解放してメモリ使用量を削減する
(public member function)