C++でvectorに要素を追加するときのreserveとemplace_back
std::vector に要素を追加するとき、最初に見ておきたいのが reserve() です。
要素数がある程度分かっているなら、先に容量を確保しておくと再確保を減らせます。
reserveする理由
#include <vector>
std::vector<int> values;
values.reserve(1000);
for (int i = 0; i < 1000; ++i) {
values.push_back(i);
}
reserve() はサイズを増やすわけではありません。
容量だけを確保します。
std::vector<int> values;
values.reserve(1000);
// values.size() は 0
// values.capacity() は 1000 以上
resize() と混同しやすいですが、役割が違います。
| 関数 | 役割 |
|---|---|
reserve() |
容量を確保する |
resize() |
要素数を変更する |
push_backとemplace_back
push_back() は、作った値をvectorに追加します。
std::vector<std::string> names;
std::string name = "alice";
names.push_back(name);
emplace_back() は、vectorの中で直接構築します。
std::vector<std::string> names;
names.emplace_back("alice");
一時オブジェクトを避けたい場合は emplace_back() が合います。
ただし、何でも emplace_back() にすればよいわけではありません。すでに値があるなら push_back() の方が読みやすいこともあります。
unique_ptrを追加する場合
std::unique_ptr はコピーできないので、push_back() する場合は std::move が必要です。
std::vector<std::unique_ptr<int>> values;
auto value = std::make_unique<int>(1);
values.push_back(std::move(value));
直接作るなら emplace_back() でも書けます。
values.emplace_back(std::make_unique<int>(1));
std::move については C++でstd::moveを使うときに気をつけること に分けています。
まとめ
std::vector に大量追加するなら、まず容量を見ます。
- 要素数が分かるなら
reserve() reserve()はサイズを増やさない- 既存の値を追加するなら
push_back() - その場で構築するなら
emplace_back() unique_ptrを移すならstd::move
性能目的で複雑にする前に、まず reserve() で再確保を減らすだけでも十分効くことがあります。


