🗄️

std::vectorの使い方(一部)

2020/09/27に公開

※よく使うものを記載。今後増えるかもしれない

  • C言語をやっていた人向け
  • C++ のバージョン: C++11

std::vector とは何か

Cでいう配列。(arrayクラスもあるがそれは置いておく)
ただしサイズは可変だし値の挿入/削除/ソートもできる。

インクルード

#include <vector>

宣言

サイズは固定値でなくてもOK

std::vector<int> array;	// サイズ0の配列
std::vector<int> array(10);	// 初期サイズ10の配列
std::vector<int> array(10, 0);	// 初期サイズ10の配列をALL 0で初期化
std::vector<int> array = {0, 1, 2};	// 初期サイズ3の配列を{0, 1, 2}で初期化
std::vector<int> array1(array);	// arrayの要素をすべてコピー

要素を追加

std::vector<int> array;
array.push_back(1);  // array[0] が1になる
array.push_back(2);  // array[1] が2になる

forループ

C言語でいう「for文で各要素に値を入れる」を例にする

int array[3];

// array = {0, 1, 2}にする
for (int i = 0; i < sizeof(array); i++) {
	array[i] = i;
}

上記と同じことをC++で行う↓

std::vector<int> array(3);

int index = 0;
for (auto iterator = array.begin(); iterator != array.end(); iterator++) {
	*iterator = index;
	index++;
}

もしくは

for (auto& iterator : array) {
	*iterator = index;
}

コピー std::copy()

  • 動作: first ~ last1つ前までresult へコピーする。
  • 引数
    • first: コピー元配列の先頭イテレータ(先頭アドレスのようなもの)
    • last :コピー元配列の終端の次のイテレータ(終端アドレスのようなもの)
    • result : コピー先配列のback_insert_iterator
      • とりあえず std::back_inserter(配列名) としておけばいい(よく分かっていない)
  • 戻り値: コピー先配列の終端の次のイテレータ
    • result + (first - last) で表す
std::copy(first, last, result);

イテレータの位置のイメージ(サイズ5の場合)

コピー配列の要素 イテレータ
0 ← first
1
2
3
4
- ← last
コピー配列の要素 イテレータ
0 ← result
1
2
3
4
- ← 戻り値

簡単な使い方

std::vector<int> src_array = {0, 1, 2};
std::vector<int> dest_array;

// src_arrayの中身をdest_arrayへすべてコピー
std::copy(src_array.begin(), src_array.end(),
	std::back_inserter(dest_array));

範囲指定してコピー

std::vector<int> src_array = {0, 1, 2, 3, 4};
std::vector<int> dest_array;

// src_array[0] ~ src_array[2] をdest_arrayへコピーする
// dest_array = {0, 1, 2} になる
std::copy(src_array.begin(), src_array.begin() + 3,
	std::back_inserter(dest_array));

std::move()

厳密にはキャストらしい。

参考: https://qiita.com/seriru13/items/e5953f88fe23e4140687

std::vector<int> src_array = {0, 1, 2};
std::vector<int> dest_array;

// src_arrayの中身をdest_arrayへすべて移動
// src_arrayは空になる(破壊的操作)
dest_array = std::move(src_array);

範囲指定して移動

std::vector<int> src_array = {0, 1, 2, 3, 4};
std::vector<int> dest_array;

// src_array[0] ~ src_array[2] をdest_arrayへ移動する
// dest_array = {0, 1, 2} になる
// src_array = {0, 0, 0, 3, 4} になる(要素はあるが、値が入っていない)
std::copy(src_array.begin(), src_array.begin() + 3,
	std::back_inserter(dest_array));

サイズを得る

2種類ある

  • size() : 要素数を得る。普通はこちらを使う
  • capacity(): メモリ上に確保されているサイズを得る。

要素の削除

※メモリは解放しない

std::vector<int> array = {0, 1, 2, 3, 4};

// 最後の1つだけ削除
array.pop_back();	// array = {0, 1, 2, 3}

// 範囲指定で削除(残った要素は前に詰められる)
array.erase(array.begin(), array.begin() + 2);	// array = {3}

// 全部削除
array.clear();	// array = {}
std::cout << array.size() << std::endl; // => 0
std::cout << array.capacity() << std::endl; // => 5

vector同士の比較

== でできる。(サイズと各要素の値を全部比較してくれる)

std::vector<int> array = {0, 1, 2, 3, 4};
std::vector<int> array1 = {0, 1, 2, 3, 4};

if (array == array1) {	// -> true

ただし、型も == をサポートしていないといけない(構造体とか)

typedef struct Temp {
	std::string name;
	int age;
} Temp;

std::vector<Temp> temp1;
std::vector<Temp> temp2;

// (初期化は省略)

if (temp1 == temp2) { // ビルドエラー

参考

Discussion