std::vector<T,Allocator>:: reserve
|
void
reserve
(
size_type new_cap
)
;
|
(constexpr C++20以降) | |
ベクターの容量(再割り当てを必要とせずにベクターが保持できる要素の総数)を、 new_cap 以上の値に増加させます。 new_cap が現在の capacity() より大きい場合、新しいストレージが割り当てられます。それ以外の場合、この関数は何も行いません。
reserve()
はベクトルのサイズを変更しません。
new_cap
が
capacity()
より大きい場合、すべてのイテレータ(
end()
イテレータを含む)および要素へのすべての参照は無効化されます。それ以外の場合、イテレータや参照は無効化されません。
reserve()
の呼び出し後は、挿入操作によってベクターのサイズが
capacity()
の値を超える場合を除き、再割り当ては発生しません。
目次 |
パラメータ
| new_cap | - | ベクターの新しい容量(要素数) |
| 型要件 | ||
-
T
は
MoveInsertable
の要件を満たさなければならない
*
this
に対して。
(C++11以降)
|
||
戻り値
(なし)
例外
- std::length_error がスローされる条件: new_cap > max_size ( ) の場合。
-
Allocator::allocate()によってスローされる例外(通常は std::bad_alloc )。
例外がスローされた場合、この関数は効果を持ちません( strong exception guarantee )。
|
|
(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) |
|
|
(
DR*
)
|
未使用のメモリを解放してメモリ使用量を削減する
(public member function) |