標準ヘッダ(標準ライブラリ)を分類しつつ、3行で紹介していく

[初心者C++er Advent Calendar](https://qiita.com/advent-calendar/2017/syoshinsya-cpper) 4日目の記事です。
前日の記事は hotwatermorning さんの [コンテナ内で最後に現れる要素を見つける](https://qiita.com/hotwatermorning/items/ec44d295798f67a1b135) です。

----------

はじめまして。norisio といいます。

C++ のコードを読んでいると、「そんな標準ヘッダがあったのか…」「どういう機能のライブラリなの？」という場面が多くあります。

また、標準ライブラリのような「道具箱」は、知らなければ、問題の解決に組み込むこと_を思いつくこと_もできません。

そこで、この記事では、標準ライブラリ（ヘッダ）をゆるく分類しながら、 __3行以内__の説明とコード片で紹介をしてみます[^1]。

[^1]: 標準は C++11 以降を対象にしています。

趣旨としては、「使える」ことではなく、__「聞いたことがあったな〜」という状態__を目指します。

さらにこの記事をきっかけに、データ構造やマルチスレッドに興味をもっていただけたらこれ以上の幸いはありません。


# 入出力系
### `<iostream>`, `<ios>`, `<istream>`, `<ostream>`
`<iostream>` は「標準出力、標準入力」（かんたんには「ターミナルへの入出力」）を扱うオブジェクト `cout`, `cerr`, `clog`, `cin` を提供する。
`<ios>`, `<istream>`, `<ostream>` は、そのようなストリームを一挙に扱うための基底クラスを提供する。

```cpp
void f(std::ostream& ost, std::string const& message){
  ost << message << std::endl;
}

int main() {
  f(std::cout, "標準出力へ");
  f(std::cerr, "標準エラー出力へ");
}
```

### `<iomanip>`
入出力ストリームの __変換方法__ を指示するための道具 __「マニピュレータ」__ を提供する。
数値の出力幅、0埋め、浮動小数の桁数を指定することなどができる。
C 言語の `printf` の第1引数に指定するフォーマットに近い機能がある。

```cpp
std::cout 
 << 3.14 << std::endl
 << std::setprecision(1)  // 浮動小数点数を出力する精度を1桁にする
 << 3.14 << std::endl;
// => 3.14
//    3
```

### `<sstream>`, `<fstream>`
`<sstream>` は、文字列 string を対象とした入出力ストリーム、
`<fstream>` は、ファイルを対象とした入出力ストリームを提供する。
`istream`/`ostream` を継承していて、`cin` や `cout` などと同じように使うことができる。

```cpp
// <iostream> の例のものと同じ
void f(std::ostream& ost, std::string const& message){
  ost << message << std::endl;
}

int main() {
  std::ofstream file("hoge.txt", std::ios::out);
  f(file, "ファイルへ");  // hoge.txt に「ファイルへ」が書き込まれる
}
```

# データ構造・コンテナ系
### `<iterator>`
下で紹介する「コンテナ」を統一的に扱うための、 __イテレータ__ に関する機能を提供する。
「インタフェースを統一することで、同じアルゴリズムを様々なコンテナに適用できる」という思想のもとにある。

参考: [イテレータの解説をするなんて今更佳代](https://qiita.com/yumetodo/items/245e94a0e85db9bf5cbb) (初心者C++er AdC 2016)

## コンテナ
__コンテナ__ は、キューやスタックのようなデータ構造を一般的な型 T のデータに対して提供するクラス群をいう[^2]。
それぞれのデータ構造で使用可能なイテレータを備えている。
構造によって得意な操作が異なり、「どのように追加・削除したいか」や、「検索の計算量」によって使い分けるとよい。

[^2]: この節には「コンテナ」に満たない「コンテナアダプタ」が含まれますが、その区別は記事の趣旨に沿わないので割愛します。

### `<array>`, `<vector>`
`<array>` は __固定長配列__ （コンパイル時にsizeが決定）、
`<vector>` は __可変長配列__ （実行時にいつでもsize変更可能）を提供する。
可変長配列は、末尾の要素のみの追加・削除を得意とする。

```cpp
std::array<int, 3>  arr;  // array にはテンプレート引数としてサイズを渡す
arr[0]    = 3;            // 通常の配列と同じアクセスができる. 範囲チェックは無い
arr.at(1) = 1;            // at を使うと添字の範囲チェックがされる
// arr.at(3) = 4;         // 添字範囲外、例外が送られる

std::vector<int>    vec1;          // vector はサイズが決まらなくても宣言できる
std::vector<float>  vec2(3);       // サイズを指定した宣言
std::vector<double> vec3(3, 3.14); // サイズと初期値(すべての要素)を指定した初期化

vec1.resize(100);                  // サイズの変更が可能
vec1.size()   // => 100
```

### `<queue>`, `<deque>`
`<queue>` は __キュー__ の構造、
`<deque>` は __両端キュー__ の構造を提供する(__d__ouble-__e__nded __que__ue)。
両端キューは、先頭・末尾の要素の追加・削除を得意とする。

```cpp
std::deque<std::string> dq;
dq.emplace_back ("丙");  // 末尾に構築
dq.emplace_back ("丁");
dq.emplace_front("乙");  // 先頭に構築
dq.emplace_front("甲");

for(auto const& element: dq){
  std::cout << element << std::flush;
}
// => 甲乙丙丁
```

### `<list>`, `<forward_list>`
`<list>` は __双方向リスト__ の構造、
`<forward_list>` は、 __単方向リスト__ の構造を提供する。
リストは、任意の位置の要素の追加・削除を得意とする。

```cpp
std::list<std::string> list;
list.emplace_back("首");  // 末尾に構築
list.emplace_back("都");
list.emplace_back("東");
list.emplace_back("京");
list.emplace_back("都");

auto itr = list.begin();  // 最初("首")を指すイテレータを取得
++itr;                    // 2つ前に進める
++itr;

list.erase(itr);          // itr の指す先(list の3つ目の要素 "東")を削除

for(auto const& element: list){
  std::cout << element << std::flush;
}
// => 首都京都
```

### `<map>`, `<unordered_map>`
__連想配列__ を提供する。
連想配列は、他のプログラミング言語では __辞書 dictionary__, __ハッシュマップ hash map__ などと[呼ばれる](https://qiita.com/dico_leque/items/86fc0e48f827c3c08f4e) ものと近い。

```cpp
std::unordered_map<std::string, float> a_human;  // キーの型 string, 値の型 float

a_human["身長"] = 129.3f;   // string をキーとしてアクセス. キーが存在しない場合は作られる
a_human["体重"] = 31.4f;

std::cout << a_human["身長"] << std::endl;  // 読み取りも同様
// => 129.3
```

### `<set>`, `<unordered_set>`
__集合__ を提供する。
重複要素のない `set`, `unordered_set`、
重複要素もありの `multiset`, `unordered_multiset` がある。

```cpp
std::set<std::string> from_prefs;
from_prefs.emplace("群馬県");
from_prefs.emplace("長野県");
from_prefs.emplace("山梨県");
from_prefs.emplace("群馬県");  // すでに存在する要素を重ねて構築する

for(auto const& element: from_prefs){
  std::cout << element << std::endl;
}
// => 山梨県
//    長野県
//    群馬県  :  2回追加したが、要素は1つしかない
```

## アルゴリズム
### `<algorithm>`
上に挙げたコンテナ達は、イテレータのインタフェースを備えている。
それを利用して、要素の __検索__, __ソート__, __条件判定__ などの操作を統一的に行える関数を提供する。

```cpp
std::vector<int> nums { 2, 7, 1, 8, 2, 8, 1, 8, 2};

// 偶数の個数を数える
auto num_of_even
  = std::count_if(std::begin(nums), std::end(nums), [](int x){return x % 2 == 0;});
std::cout << num_of_even << std::endl;
// => 6

// 奇数のみ取り出してくる
decltype(nums) odds;
std::copy_if(std::begin(nums), std::end(nums), std::back_inserter(odds),
             [](int x){return x % 2 != 0;});
for(auto element: odds){
  std::cout << element << ", ";
}
// => 7, 1, 1,
```


### `<numeric>`
イテレータを利用し、__整数列(連番)__を生成する関数、
連続する要素の__和（総和、部分和）__、隣接要素の__差__、
2つの連続する要素の__内積__ といった数値的な処理を提供する。

```cpp
std::vector<int> seq(10);

// seq を連番で初期化する
std::iota(std::begin(seq), std::end(seq), 1);           // 第3引数 は 連番の初期値

// seq => 1, 2, ..., 10

// seq の総和を取る
auto sum
  = std::accumulate(std::begin(seq), std::end(seq), 0); // 第3引数 は 加法の零元を渡す

std::cout << sum << std::endl;
// => 55
```

## コンテナでない、データ格納系
### `<valarray>`
数値計算に特化した __配列__ `valarray` を提供する。
`vector` に似ているが、 `valarray` どうしの演算子が定義されており、要素指向計算が書きやすい。
コンパイラによる[SIMD 化の恩恵も受けやすい](
https://msmania.wordpress.com/tag/simd/)。

### `<bitset>`
__ビット集合__ を提供する。
`bitset` どうしの論理演算や、特定ビットへのアクセスを行うことができる。

```cpp
std::bitset<8> octet[4];  // 8bit の bitset を4つ持つ配列
octet[3].set(7);          // 下位ビットから7番目 (つまり最上位ビット) を 1 にする
octet[3].set(6);

octet[2].set(7);
octet[2].set(5);
octet[2].set(3);

octet[0].flip();          // ビットを反転する

for(int i=3; i>=0; --i){
  std::cout << octet[i] << " ";
}
// => 11000000 10101000 00000000 11111111

std::cout << std::endl;
for(int i=3; i>=0; --i){
  std::cout << octet[i].to_ulong() << ".";
}
```

### `<tuple>`
__タプル__ を提供する。
タプルは、型の異なる複数の要素をまとめて扱うことができる。
格納する型の種類・順番はテンプレート引数であり、コンパイル時に決定している必要がある。

```cpp
std::tuple<std::string, int> make_student(){
  // std::make_tuple 関数で簡単にタプルの値を生成できる
  return std::make_tuple(std::string("スネ夫"), 11);
}

int main(){
  std::string name;
  int age;
  
  // tie は、変数への参照からなる tuple を生成する
  // そこに tuple を代入することで多値代入を再現できる
  std::tie(name, age) = make_student();
  
  std::cout << name << "(" << age << ")" << std::endl;
}
```


### `<functional>`
__関数オブジェクト__ `function` を提供する。
`function` には、`()` で呼び出すことのできるものを全て格納できる。
そのほかにも、__引数の部分適用__や、__四則演算__などの関数オブジェクト自体も提供する。

```cpp
void hello(){
  std::cout << "Hello" << std::endl;
}

int main() {
  std::function<void()>        f1, f2;   // void(): 返り値がvoid, 引数なしの関数
  std::function<int(int, int)> f3;       // int(int, int): 返り値がint, 引数がint 2つの関数
  
  f1 = hello;             // フリー関数 hello の関数ポインタ
  f2 = [](){std::cout << "Good evening" << std::endl;};  // ラムダ式(関数オブジェクト)
  f3 = std::plus<int>();  // <functional> で提供される「int同士を加算する」関数オブジェクト
  
  f1();             // => Hello
  f2();             // => Good evening
  std::cout << f3(1000, 500);  
                    // => 1500
}
```

# ユーティリティ系
### `<memory>`, `<scoped_allocator>(省略)`
`<memory>` は、__スマートポインタ__などのメモリ確保・解放関連機能を提供する。
スマートポインタは、動的に確保したメモリを管理し、自動で解放するクラスである。

```cpp
struct SomeClass{
  int member;
  void printMember(){
    std::cout << member << std::endl;
  }
  
  SomeClass(){
    std::cout << "Constructed" << std::endl;
  }
  ~SomeClass(){
    std::cout << "Destructed" << std::endl;
  }
};

int main() {
  // new した SomeClass へのポインタの管理を unique_ptr に任せる
  std::unique_ptr<SomeClass> ptr_to_instance( new SomeClass );
  
  // 通常のポインタと同様に "->" でメンバにアクセスできる
  ptr_to_instance -> member = 42;
  ptr_to_instance -> printMember();

  // スコープが終わり変数の寿命が尽きると、自動でインスタンスが破棄される
}

// => Constrcuted
//    42
//    Destructed
```

### `<chrono>`
__時計・計時関連__ の機能を提供する。
システムの時刻を取得する、プログラム内で経過時間を計測することなどが可能。
時間単位（秒、分など）のクラスも提供され、キャストにより換算ができる。

```cpp
using std::chrono::system_clock;
using std::chrono::duration_cast;
using std::chrono::seconds;

// 処理の開始時刻と終了時刻を記録することで、処理時間を測定する
system_clock::time_point begin = system_clock::now();
very_long_processing();
system_clock::time_point end   = system_clock::now();

// time_point(時刻) - time_point(時刻) の演算は duration(幅を持つ時間) を返す
auto duration_of_process( end - begin );

// seconds(秒) 単位に変換し、数値として表示
std::cout << duration_cast<seconds>(duration_of_process).count() << std::endl;
```

### `<regex>`
__正規表現__ を提供する。

### `<locale>`
__国ごとに異なる表現__ （日付・時刻・通貨） を扱うためのクラス・関数を提供する。

# 数値系
### `<complex>`
__複素数__ を提供する。

```cpp
std::complex<double> z(20.0, 30.0);

z.real();     // 実部 20.0
z.imag();     // 虚部 30.0
std::abs(z);  // 絶対値 36.06
std::arg(z);  // 偏角(rad) 0.983
std::conj(z); // 複素共軛 (20.0, -30.0)

decltype(z) z2(0.5, 1.2);

z + z2;  // 加算 (20.5, 31.2)
``` 

### `<random>`
__乱数__ を提供する。

```cpp
/*
 * ハードウェア乱数は周期をもたないが, 低速である.
 * 擬似乱数は周期をもつが, 高速である.
 * 一般的な使い方では, 十分に周期の長い擬似乱数生成器(mt19937など)を, 
 * ハードウェア乱数を使って初期化する. 以降は擬似乱数生成器の返す結果を用いる.
 */
std::random_device seed_generator;         // 擬似乱数シードのためのハードウェア乱数
std::mt19937 rnd_engine(seed_generator()); // メルセンヌツイスタ擬似乱数をシードで初期化

double constexpr dist_mean   = 50.0;
double constexpr dist_stddev = 10.0;
std::normal_distribution<> dist(dist_mean, dist_stddev); // 正規分布: 平均と標準偏差を与える

dist(rnd_engine);  // => 分布 dist にしたがった乱数が生成される
```

# "コンパイル時処理" 系
### `<type_traits>`
型特性を提供する。
型特性とは、`const/volatile` 修飾の有無や、特定の演算の可否などの、型に関する情報。
テンプレートで受け取った型ごとに処理を変えるときなどに利用される。

```cpp
// 「型が符号付き算術型か」
static_assert(std::is_signed<int>::value,          "");  // OK
static_assert(std::is_signed<unsigned int>::value, "");  // assertエラー

// 「型が const 修飾されているか」
static_assert(std::is_const<float>::value,       "");  // assertエラー
static_assert(std::is_const<float const>::value, "");  // OK

// 型の const 修飾を除去
using new_type = std::remove_const<double const>::type;
// 「型が同一かどうか」
static_assert(std::is_same<new_type, double>::value, ""); // OK
```

### `<ratio>`
__コンパイル時有理数計算__ を提供する。

# マルチスレッド系
### `<thread>`
__スレッド__ を提供する。
スレッドとは、1つのプロセス内に1つ以上並行で流れる、プログラムのコンテキストをいう。
「あるスレッドが IO を待つ間、他のスレッドが計算をする」等の並行・並列処理を可能にする。

```cpp
std::thread
  th1( [](){ /* 処理1 */ } ),
  th2( [](){ /* 処理2 */ } );  // スレッドが2つ起動され、処理1, 処理2が並行で行われる

th1.join();
th2.join();  // 2つのスレッドの終了を待つ
```

### `<atomic>`
__アトミック操作__ や、それが可能かどうかのフラグを提供する。
アトミック操作とは、 CPU への命令が分割されない、「最小の」操作であり、
マルチスレッドプログラムで必要になることがある。

### `<mutex>`, `<shared_mutex>`
__相互排他__ を提供する。
相互排他(mutex = mutual exclusion) とは、あるスレッドがリソースを使用する際、
他のスレッドと同時に、そのリソースを操作（データ競合）しないようにする仕組みである。

### `<condition_variable>`
__条件変数__ を提供する。
条件変数(condition variable) とは、特定の条件が満たされるまでスレッドの実行を止めることで、
データ競合を防ぐ仕組みである。

### `<future>`
__非同期実行__ のパターンを構築するための、
`future`, `promise` クラス、 `async()` 関数などを提供する。

参考: [C++で簡単非同期処理(std::thread,std::async)](https://qiita.com/termoshtt/items/d3cb7fe226cdd498d2ef)

# 言語サポート系
### `<new>`
グローバルな `operator new` を定義する。
また、メモリ確保に失敗した場合に関する型・関数や、例外についての機能も提供する。

### `<typeinfo>`, `<typeindex>`
__実行時型情報(RTTI)__ に関する機能を提供する。
RTTI とは、ポリモーフィックな型の実体に対して、実行時にその実体の型を取得できることをいう。

関連: `dynamic_cast`
参考: [C++のtypeidとtype_infoとtype_index](https://cpplover.blogspot.jp/2014/10/ctypeidtypeinfotypeindex.html)

### `<exception>`, `<stdexcept>`
`<exception>` は__例外__ に関する機能を提供し、 `<stdexcept>` は、一般的な例外クラスを提供する。
`<stdexcept>` の例外クラスは、`logic_error` と `runtime_error` に分類される。

### `<system_error>`
OS が出力するエラーを例外として扱う機能を提供する。


# おわりに

boost などのヘッダオンリーライブラリであっても、各開発環境に用意するのは少し手間のかかるものです。
標準ライブラリを活用して、可搬性の高いプログラムを書きたいですね。
明日は、 sumomoneko さんです。