C++ STL vectorのコード集

# 概要
STL（Standard Template Library）の`vector`関係のコード集です。対応確認環境はMicrosoft Visual Studio 2019 Communityのstd:c++latest (C++20 draft)です。最新のC++では制約が異なる可能性があります。

# 共通事項

- `using namespace std;`により`std::`は省略しています。

## 出力用の関数

出力用に次の関数を定義しています。共通部分なので以降のコードでは省略します。

### 一行に出力
```cpp
template <typename T>
void output_singleline(const vector<T>& v)
{
	constexpr wchar_t sep[] = L", ";
	wstringstream wss;
	for (const auto& i : v)
	{
		wss << i << data(sep);
	}
	if (const auto& s = wss.str(); !empty(s))
	{
		wcout << s.substr(0, s.length() - size(sep) + 1);
	}
	wcout << endl;
}
```

# 部分のコピーを作成する

`vector`コンストラクタにイテレータを与えることで部分のコピーを作成できます。

```cpp
#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

template <typename T>
void output_singleline(const vector<T>& v);

int main()
{
	vector<int> v1 = {0, 1, 2, 3, 4};
	// 先頭から1個、末尾から2個を飛ばしてコピー
	vector<int> v2(next(begin(v1), 1), prev(end(v1), 2));

	wcout << L"v1: ";
	output_singleline(v1);
	wcout << L"v2: ";
	output_singleline(v2);

	return 0;
}
```

```plain:出力
v1: 0, 1, 2, 3, 4
v2: 1, 2
```

# 部分のコピーを別の`vector`に追加する

```cpp
#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

template <typename T>
void output_singleline(const vector<T>& v);

int main()
{
	vector<int> v1 = {0, 1, 2, 3, 4};
	vector<int> v2 = {5, 6, 7};
	// 先頭から1個、末尾から2個を飛ばしてコピー追加
	// end(v2)は末尾への追加です。begin(v2)で先頭に追加します。
	// nextやendと組み合せて途中も指定できます。
	v2.insert(end(v2), next(begin(v1), 1), prev(end(v1), 2));

	wcout << L"v1: ";
	output_singleline(v1);
	wcout << L"v2: ";
	output_singleline(v2);

	return 0;
}
```

```plain:出力
v1: 0, 1, 2, 3, 4
v2: 5, 6, 7, 1, 2
```

# 別の`vector`に全要素をムーブ（譲渡）する

`vector`を`move`に渡して別の`vector`に代入することで全要素をムーブ（譲渡）できます。作成した`vector`を`map`のキーに使う場合などに使います。

```cpp
#include <iostream>
#include <vector>

using namespace std;

template <typename T>
void output_singleline(const vector<T>& v);

int main()
{
	vector<int> v1 = {0, 1, 2, 3, 4};
	vector<int> v2 = move(v1);

	wcout << L"v1: ";
	output_singleline(v1);
	wcout << L"v2: ";
	output_singleline(v2);

	return 0;
}
```

```plain:出力
v1:
v2: 0, 1, 2, 3, 4
```

## 一部を別の`vector`にムーブ（譲渡）する

`move`ではイテレータの指す要素は変更されますが`vector`の構造は変更されません。ムーブ後の要素は`erase`により意図的に削除する必要があります。

```cpp
#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

template <typename T>
void output_singleline(const vector<T>& v);

int main()
{
	// vector<int>はintの仕様によりmoveしても譲渡せずコピーされます。
	// vector<wstring>はwstringの仕様によりムーブ（譲渡）されます。
	vector<wstring> v1{L"0", L"1", L"2", L"3", L"4"};
	vector<wstring> v2{L"5", L"6", L"7"};
	// 先頭から1個、末尾から2個を飛ばした部分を末尾へ譲渡
	// 元のvectorの対象部分は無効な文字列が残ります。
	move(next(begin(v1), 1), prev(end(v1), 2), insert_iterator(v2, end(v2)));

	wcout << L"（erase前）" << endl;
	wcout << L"v1: ";
	output_singleline(v1);
	wcout << L"v2: ";
	output_singleline(v2);

	// 無効な文字列は手動で削除します。
	v1.erase(next(begin(v1), 1), prev(end(v1), 2));

	wcout << L"（erase後）" << endl;
	wcout << L"v1: ";
	output_singleline(v1);
	wcout << L"v2: ";
	output_singleline(v2);

	return 0;
}
```

出力の（erase前）で`move`の対象となった要素に空文字列が指定されていることが分かります。

```plain:出力
（erase前）
v1: 0, , , 3, 4
v2: 5, 6, 7, 1, 2
（erase後）
v1: 0, 3, 4
v2: 5, 6, 7, 1, 2
```