GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing cpprefjp.github.io — std::vector - cpprefjp C++日本語リファレンス class template <vector> std::vector
配列と違い、ストレージは
これらの挙動は配列と同じパフォーマンス特性を示し、加えてストレージサイズの変更が非常に簡単である。ただし、 他の標準シーケンスコンテナと比べ、 内部的には、 領域の再確保が発生すると、全ての要素が新しい領域にコピーされるため非常にコストがかかる。このため、最終的な要素数が大きくなると解っている場合はあらかじめ 各テンプレートパラメータの意味は次の通りである。
リファレンス中では、これらの名前をテンプレートパラメータとして扱う。 概念・前提知識メンバ関数構築・破棄
イテレータ
領域
要素アクセス
コンテナの変更
アロケータ
メンバ型
非メンバ関数比較演算子
入れ替え
要素削除
推論補助
|
| 名前 | 説明 | 対応バージョン |
|---|---|---|
template <class T> struct hash; |
hashクラスの先行宣言 |
C++11 |
template <class Allocator> struct hash<vector<bool, Allocator>>; |
hashクラスのvector<bool>に対する特殊化 |
C++11 |
| 名前 | 説明 | 対応バージョン |
|---|---|---|
template <class T, class charT> requires is-vector-bool-reference<T>struct formatter<T, charT>; |
vector<bool>::referenceをboolとして出力するためのformatterの特殊化 |
C++23 |
#include <iostream>
#include <cassert>
#include <vector>
int main()
{
// int型を要素とする可変長配列の変数を定義し、
// 初期状態の要素を設定
std::vector<int> v = {1, 99, 4};
v[1] = 3; // 1番目の要素を参照し、書き換える
v.push_back(5); // 末尾に値5を追加
v.insert(v.begin() + 1, 2); // 1番目に値2を挿入
int* p = v.data(); // 内部表現のポインタを取得
std::size_t size = v.size(); // 要素数を取得
assert(p[0] == 1);
assert(size == 5u);
// 各要素に対して操作を行う
for (int x : v) {
std::cout << x << std::endl;
}
}
1
2
3
4
5
不完全型を要素型に出来るようになった事で、階層構造や多分木などの再帰的データ構造を実装することが容易になる。
他にも、listとforward_listが不完全型をサポートしている。
#include <iostream>
#include <vector>
#include <string>
#include <utility>
//簡易なディレクトリ構造表現クラス
class directory {
//不完全型(クラス定義内ではそのクラス自身は不完全)を要素型に指定
std::vector<directory> m_subdir{};
std::string m_name{};
public:
directory(const char* name) : m_name{name}
{}
//サブディレクトリ追加
template<typename Dir>
void add(Dir&& dir) {
m_subdir.emplace_back(std::forward<Dir>(dir));
}
//ディレクトリ名取得
auto get() const -> const std::string& {
return m_name;
}
auto begin() const {
return m_subdir.begin();
}
auto end() const {
return m_subdir.end();
}
};
//ルートより下のディレクトリについて整形して出力
void recursive_out(const directory& dir, unsigned int depth) {
if (1 < depth) std::cout << "| ";
for (auto i = depth; 2 < i; --i) {
std::cout << " ";
}
if (2 < depth) std::cout << " ";
std::cout << "|-" << dir.get() << std::endl;
for (auto& subdir : dir) {
recursive_out(subdir, depth + 1);
}
}
//ディレクトリ構造を出力する
void out_directorytree(const directory& dir) {
std::cout << dir.get() << std::endl;
for (auto& subdir : dir) {
recursive_out(subdir, 1);
}
}
int main() {
directory dir{"root"};
dir.add("sub1");
directory sub2{"sub2"};
sub2.add("sub2.1");
directory sub22{"sub2.2"};
sub22.add("sub2.2.1");
sub2.add(std::move(sub22));
dir.add(std::move(sub2));
dir.add("sub3");
out_directorytree(dir);
}
root
|-sub1
|-sub2
| |-sub2.1
| |-sub2.2
| |-sub2.2.1
|-sub3
vector<bool>の基本操作#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<bool> v(8, false);
v[5] = true; // ビットを立てる
v[7].flip(); // ビット反転(1だったら0、0だったら1にする)
//bool& x = v[3]; // エラー!プロキシオブジェクトのため、bool&には変換できない
bool x = v[3]; // OK : コピーはできる
std::cout << "v[3] : " << x << std::endl;
// イテレータ操作は可能
std::for_each(v.begin(), v.end(), [](bool x) {
std::cout << x << std::endl;
});
}
v[3] : 0
0
0
0
0
0
1
0
1
vector<bool>の要素は参照するとプロキシオブジェクトのコピーが返ってくるため、RandomAccessIteratorの要件を満たさない。
ただし、C++20以降のランダムアクセスイテレータの定義であるrandom_access_iteratorのモデルは満たす。
#include <cassert>
#include <vector>
constexpr bool f()
{
std::vector<int> v = {1, 2, 3};
v.push_back(4);
auto* p = v.data();
assert(p);
int sum = 0;
for (auto x : v) {
sum += x;
}
return sum != 0;
}
int main()
{
static_assert(f());
}
vectorのメモリ効率について
vector be contiguous?vectorの要素のメモリが連続していることが保証された。vector<bool>: More Problems, Better Solutionsbitset(ビットを格納する固定長コンテナ)も参照。dynamic_bitsetがある。pair、tupleのフォーマット出力、および文字・文字列のデバッグ指定 ("?") が追加されたvector<bool>::referenceにADLで見つかる非メンバswap関数が追加され、従来のstaticメンバ関数版swapが非推奨となったvector<bool>::swap(reference, reference) not definedvector<bool>::reference同士を交換する静的メンバ関数swap()の効果が規定された。宣言のみで意味が規定されていなかった