C++11を浅〜くまとめる 後編

[前回](https://qiita.com/yskszk/items/1310923f9e98bf1b5819)の続きです。
予告通り、ライブラリーに関する新機能をまとめます。


## ライブラリ更新(コンテナ)

### std::array

Cの配列を便利にしたようなコンテナ。
```std::vector``` のような可変長ではありませんが、パフォーマンスは ```std::vector``` より良いです(Cの配列と同じアセンブリになるらしい)。
Cの配列と違って境界チェックがあり、範囲外にアクセスしようとすると例外を投げます。

```c++
std::array<int, 4> a = { 1, 2, 3, 4 };
a[4] = 0;    // [] は境界チェック無し
a.at(4) = 0;    // at は境界チェック有り(例外発生)
```


## ライブラリ更新(イテレータ)

### std::next / std::prev

イテレーターを進めたり戻したりした結果を返します。
引数のイテレーターが進んだり戻ったりはしません。

```c++
std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
std::vector<int>::iterator iterator = v.begin();
std::vector<int>::iterator it1 = std::next( iterator );
std::vector<int>::iterator it2 = std::next( it1, 4 );
std::vector<int>::iterator it3 = std::prev( it2 );
std::vector<int>::iterator it4 = std::prev( it3, 2 );
printf( "%d, %d, %d, %d, %d\n", *iterator, *it1, *it2, *it3, *it4 );
// 結果は 0, 1, 5, 4, 2
```


### std::begin / std::end

配列(コンテナ)の先頭イテレーターや末尾の次のイテレーターを取得します。
コンテナだけでなく、C配列でも使用できます。

```c++
//  v1 や v2 の型は 
std::vector<int> v = { 0, 1, 2, 3, 4, 5 };
std::vector<int>::iterator v1 = std::begin( v );
std::vector<int>::iterator v2 = std::end( v );

int a[] = { 6, 7, 8, 9 };
int* a1 = std::begin( a );
int* a2 = std::end( a );
```


## ライブラリ更新(アルゴリズム)

### std::all_of / std::any_of / std::none_of

範囲内の要素が条件を満たすか確認できます。
```all_of``` は全要素が条件を満たした場合、```any_of``` は要素が１つでも条件を満たした場合、```none_of``` は全要素が条件を満たさなかった場合に true を返します。
(加えて、範囲が空の場合も true を返します。)

```c++
// 条件 = ５以下
auto condition = [](int x) {
    return (x <= 5);
};

std::vector< int > v = { 1, 2, 3, 4, 5 };
// 全てが５以下か？
bool a = std::all_of( v.begin(), v.end(), condition );    // a == true
// １つでも５以下の要素があるか？
bool b = std::any_of( v.begin(), v.end(), condition );    // b == true
// 全てが６以上(５以下ではない)か？
bool c = std::none_of( v.begin(), v.end(), condition );    // c == false
```


### std::min / std::max

複数の値のうち、もっとも小さい/大きい値を取得することができます。

```c++
int a = std::min( 5, 6 );    // a == 5
int b = std::max( 5, 6 );    // b == 6
```

３つ以上の値を扱うこともできます。

```c++
int a = getValue1();
int b = getValue2();
int c = 10;
int d = std::min( { a, b, c, 5 } );
```


## ライブラリ更新(メモリ管理)

### std::shared_ptr

リソースの所有権を共有するためのスマートポインタです。
所有者が 0 になると、自動的にリソースが解放されます。
これにより、解放忘れによるメモリーリークを回避することができます。

```c++
{
    // リソース生成(所有者は1人)
    std::shared_ptr<int> p1( new int( 10 ) );

    {
        // リソースを共有(所有者が2人になる)
        std::shared_ptr<int> p2 = p1;
    }
    //  p2 が破棄される(所有者が1人に戻る)
}
// p1 が破棄される(所有者がいなくなる) -> リソースが破棄される
```

```shared_ptr``` リソースへの弱参照を保持する ```weak_ptr``` もあります。
所有権は保持しませんが、リソースにアクセスできるので、循環参照を解決するために使われます。

```c++
// リソース生成
std::shared_ptr<int> p1( new int( 10 ) );

// リソースを監視
std::weak_ptr<int> p2 = p1;

{
    // 監視しているリソースの shared_ptr を取得
    std::shared_ptr<int> p3 = p2.lock();
    if ( p3 ) {
        int a = *p3;    // a == 10
    }
}

// 所有権を放棄 -> リソースが破棄される
p1.reset();

if ( p2.expired() ) {
    // リソースはリンク切れ
}

{
    std::shared_ptr<int> p3 = p2.lock();
    if ( p3 ) {
        // リンク切れなので p3 == nullptr
    }
}
```


### std::unique_ptr

リソースの所有権を１人が保持するためのスマートポインタです。
```shared_ptr``` のようにリソースを共有することはできません。
コピーはできませんが、ムーブで所有権を譲渡することは可能です。
ポインタが破棄されると、自動的にリソースが解放されます。

```c++
{
    // リソース生成
    std::unique_ptr<int> p1( new int( 10 ) );
}
// p1 が破棄され、リソースが破棄される
```


## ライブラリ更新(文字列処理)

### std::u16string / std::u32string

UTF-16 および UTF-32 用の文字列型です。


### std::to_string

整数や実数の値を文字列に変換します。

```c++
std::string s1 = std::to_string( 10 );
std::string s2 = std::to_string( 3.14 );
```


### std::stoi / std::stof

文字列を整数や実数に変換します。
```stoi``` と ```stof``` 以外にも色々あります。

```c++
int v1 = std::stoi( "10" );
float v2 = std::stof( "3.14" );
double v3 = std::stod( "3.14" );
```


## ライブラリ更新(関数オブジェクト)

### std::function

関数ポインタやラムダ式など、関数なら何でも保持できるクラスです。

```c++
bool isEven( int v ) {
    return ( v % 2 == 0 );
}

int main() {
    std::function<bool(int)> func = isEven;
    bool b1 = func( 10 );    // b1 == true
    bool b2 = func( 11 );    // b2 == false

    //  nullptr を代入するとクリア.
    func = nullptr;
    
    bool b3 = func( 12 );    // bad_function_call 例外発生
}
```

ラムダ式を関数の引数に渡す際の型として使えます。

```c++
// cond が true なら "yes" を出力
void sayYes( int v, std::function<bool(int)> cond ) {
    if ( cond( v ) ) {
        std::cout << "yes" << std::endl;
    }
}

int main() {
    // "yes" が出力される
    sayYes( 10, []( int v ) -> bool {
        return ( v % 2 == 0 );
    });
}
```


## ライブラリ更新(並列処理)

### std::thread

スレッドを作成できるようになりました。

```c++
// 1秒スリープするだけのスレッド
std::thread t( []{
    sleep( 1 );
} );

auto start = std::chrono::system_clock::now();

// スレッドの終了を待つ
t.join();

auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast< std::chrono::milliseconds >( end - start ).count();
```

```elapsed``` は ```1000``` になり、１秒スリープするのを待っていたことが分かります。


### std::mutex

共有リソースを排他制御するためのクラスです。
```std::lock_guard``` 生成時にリソースをロックし、破棄時にロックを解除するという使い方が一般的です。

```c++
std::mutex m;
std::vector<int> v;

void pushBack( int i ) {
    std::lock_guard<std::mutex> lock(m);
    v.push_back( i );
    sleep( 1 );
    v.push_back( i + 1 );
}

int main(void){
    std::thread t1( []{
        pushBack( 1 );
    } );
    std::thread t2( []{
        pushBack( 10 );
    } );
    t1.join();
    t2.join();
}
```

```v``` の中身は ```1, 2, 10, 11``` になります。


## ライブラリ更新(汎用的なユーティリティ)

### std::tuple

C++ でもタプルが使えるようになりました。
２つしか値を扱えない ```std::pair``` とは違い、```std::tuple``` は何個の値でも扱えます。
```std::make_tuple``` でタプルを作成し、```std::get``` でタプルの要素を取得できます。

```c++
std::tuple<std::string, int, int, int> red = std::make_tuple( "red", 255, 0, 0 );
printf( "%s = (r:%d, g:%d, b:%d)\n", std::get<0>(red).c_str(), std::get<1>(red), std::get<2>(red), std::get<3>(red) );
```

### chrono

時間関連の処理を行うクラス/関数が追加されました。
色々な機能がありますが、最も一般的なのは経過時間の測定だと思います。
下記のように処理を ```start``` と ```end``` で囲むことで経過時間を測定することができます(以下の ```elapsed``` はミリ秒単位の整数値になります)。

```c++
auto start = std::chrono::system_clock::now();
sleep( 1 );
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast< std::chrono::milliseconds >( end - start ).count();
```


### type_traits

型の特性を判定する仕組みが追加されました。
主に ```static_assert``` や SFINAE で使用できます。

例えば、以下のテンプレート関数がある場合、```+ operator``` が定義されている型なら、どんな型でも使えます。

```c++
template <typename T>
T add( T a, T b ) {
    return ( a + b );
}

// int も double も std::string も通る
int i = add<int>( 1, 2 );
double d = add<double>( 2.0, 3.0 );
std::string s = add<std::string>( "3.0", "4.0" );
```

以下の２つの方法で、```T``` を整数に限定できます。
```T``` が ```double``` や ```std::sring``` の場合、コンパイルエラーになります。

```c++
template <typename T>
T add( T a, T b ) {
    // T が整数でなければコンパイル時にエラーになる
    static_assert( std::is_integral<T>::value, "T must be integral or floating point." );
    return ( a + b );
}
```

```c++
// T が整数でなければコンパイル時にエラーになる
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
T add( T a, T b ) {
    return ( a + b );
}
```


## ライブラリ更新(正規表現ライブラリ)

### regex

正規表現が使えます。

```c++
std::array<std::string, 7> texts = {
    "apple", "banana", "orange", "lemon", "mango", "grape", "melon"
};

// 末尾が on の文字列を探す
std::smatch match;
std::regex pattern1( "on$" );
for ( auto text: texts ) {
    if ( std::regex_search( text, match, pattern1 ) ) {
        std::cout << text << std::endl;
    }
}

// a から e までの文字列を * に置換
std::string string( "*" );
std::regex pattern2( "a.*e" );
for ( auto text: texts ) {
    auto newText = std::regex_replace( text, pattern2, string );
    std::cout << text << " -> " << newText << std::endl;
}
```