C++の個人的まとめ

# この記事はなに?
C++を使ってきて調べたことや知ったことをまとめました。
個人的にはかなりの分量です。

この部分は敬体ですが、文自体は常体で書いてあります。

# C++のまとめ
## C++のバージョン
C++はISOとIECが共同でで標準化している。
規格には古いものから新しい物まで様々ある。

| C++規格 | 現在の略称 | 策定中の略称 |
|:-------:|:----------:|:------------:|
| ISO/IEC 14882:1998 | C++98 | 不明 |
| ISO/IEC 14882:2003 | C++03 | 不明 |
| ISO/IEC 14882:2011 | C++11 | C++0x |
| ISO/IEC 14882:2014 | C++14 | C++1y |
| ISO/IEC 14882:2017 | C++17 | C++1z |

略称はコンパイラのオプションで使われることがある。
例えばGCC(g++)ではC++11を有効化するときは`-std=c++11`オプションを入れる。

策定中の略称はコンパイラのオプションで使うことができる場合がある。
あくまで策定中なので、未対応の部分があったりする可能性がある。
いち早く、最新の機能を取り入れたかったり、古いコンパイラでも策定された規格の一部を使いたい時に使うと良い。
ただし、すでに対応済みの規格がある場合はそちらを使うべき(C++11対応なのにC++0xを使う意味はない)
## nullptr
NULLなポインタを示すための値。

nullptrを使うことでポインタとしてnullを表すことができるようになった。

## C++スタイルキャスト
C++はCから引き継いだキャストとC++独自のキャストがある。

C++のキャストには4種類ある。

### static_cast
一般的なキャスト、他のキャストと違い使わないほうが良いとは言われていないキャスト。
コンパイル時に処理される。
このキャストで解決きないようなキャストは設計に問題がある可能性がある。

### const_cast
constとvolatileの付け外しができるキャスト。
constは意味があってconstが付いていることがほとんどなので使うべきでない。
コンパイル時に処理される。

### reinterpret_cast
型の違うポインタへの変換やポインタから整数への変換に使われるキャスト。
しかし、一度`void*`を経由すれば`static_cast`でできるので基本的に使うべきでないキャスト
コンパイル時に処理される。

### dynamic_cast
ダウンキャストに使われる演算子。
ダウンキャストは基底クラスから派生クラスへのキャスト(継承に関しては後述)。
キャスト対象の型を見て、問題なければキャストし問題があれば`nullptr`か例外が投げられる(例外は後述)。

型情報を必要とするためRTTIが必要になるので、コンパイルオプションに注意が必要である。

実行時に処理される。

## 参照
C++は万能なポインタの機能を制限した機能として参照を追加した。

参照はオブジェクトそのものを渡しているわけではないため、
場合にもよるが概ねオブジェクトサイズよりもデータ量が小さくなる。
参照を利用することで大きなオブジェクトを関数に大きなコピーを起こさずに渡すことができる。

参照はconst参照が使われることが多い。
const参照は読み込み専用な参照型で渡した先で値を書き換えるということはできない。
なので、データを読みたいだけの関数で引数をconst参照にすることで、
メモリ上のデータを増やさず比較的高速にデータの受け渡しが可能になる。

```c++
struct big_data {
    int data[20000];
};

void func1(big_data); // int[20000]がコピーされる。
void func2(const big_data&); // int[20000]ではなく参照がコピーされる。
```

また、データの変更をしたい時はconstをつけず普通に参照を取り、送られたデータを改変することでデータの変更ができる。

```c++
struct data {
    int number;
};

void func(data& d) {
    d.number = 1; // 送られたデータを変更する
}
```

## コンパイル時定数
コンパイル時定数はコンパイル時に値が完全に解決可能である値のことを言う。
例えば`1`などの値はコンパイル時定数となる。

C++11からはコンパイル時定数を表すものとして`constexpr`が追加された。

```c++
constexpr int ZERO = 0;

constexpr int get_one() {
    return 1;
}
```

constexpr変数は右辺に来る値がコンパイル時定数である必要がある以外はほとんど`const`と同じように扱える。

constexpr関数はC++11では制限が強く(returnはひとつだけ、whileは使えないなど)使いにくいものであったが、
C++14からはこの制限が緩和され一般的な関数と遜色ないくらいになった。

constexpr関数はコンパイル時定数が必要な文脈ではコンパイル時に計算が行われその値が使われる。
対して、コンパイル時定数が必要でない文脈では実行時に実行される普通の関数として使われる。

また、constexpr関数は一般的に副作用がない(グローバル変数の書き換えができないなどによる)ものとなる。

## オーバーロード
### 関数のオーバーロード
同名の関数を特定の条件を満たせば複数定義できる機能をオーバーロードという。

オーバーロードを行う条件としてはシグネチャが異なる必要がある。
シグネチャは次のものである。

+ 関数の名前
+ 引数の数
+ 引数の型

このどれかが違えばいくらでも関数を作ることができる。
ただし、ここに含まれていない返り値の型だけが異なる関数は作ることができないので注意が必要である。

```c++
void func(int);
void func(int, int); // 引数の数が異なる
void func(float); // 引数の型が異なる
// int func(int); // 返り値の型だけが異なるものは作れない
``` 

### 演算子のオーバーロード
C++は演算子のオーバーロードをサポートしている。

例えば、ポインタを模倣したクラスがあったとして、+1の処理を行いたいとする。
もしも、演算子のオーバーロードがなければadd(1)のようになってしまい、全くポインタらしさがなくなってしまう。

C++ではほとんどの演算子をオーバーロード可能である。

```c++
struct pointer {
    int n;

    pointer& operator+=(int num) {
        n += num;
        return *this;
    }
};

pointer p = {};
p += 2;
```
この例では`+=`演算子をオーバーロードしている。

一般に?演算子をオーバーロードしたい場合
`operator ?`という名前の関数を作れば良い。

例えば`+`であれば`operator+`、`()`(関数呼び出し)であれば`operator()`という感じである。

また、引数が基本型以外を含む場合非メンバ関数(メンバ関数や非メンバ関数に関しては後述)で定義することができる。

```c++
struct pointer {
    int n;
};

pointer operator+(pointer lhs, const pointer& rhs) {
    lhs.n += rhs.n;
    return lhs;
}
```
上記の例では二項の`+`演算子を非メンバ関数としてオーバーロードしている。

## 名前空間
C++は名前空間を持つ言語である。
C++風の名前空間を持つ言語としてはC#がある。

C++の名前空間は名前を他の名前空間と分離することができる機能である。

```c++
// ===== これは正しくない例 =====
struct data {...};
struct data {...}; // 名前がかぶっている

// ===== 名前空間を使った例 =====
namespace a {
    struct data {...};
} /* a */

namespace b {
    struct data {...}; // 異なる名前空間なのでかぶらない
} /* b */
```

名前空間の中にアクセスするには`::`(スコープ解決演算子)を使う

```c++
namespace ns {
    struct data {...};
} /* ns */

// 使う側
ns::data d;
```

### 無名名前空間 (unnamed-namespace)
C++では名前空間に名前をつけないということができる。
この機能を無名名前空間と呼ぶ。
無名名前空間に含まれる識別子は内部リンケージをもつ。
そのため、ソースファイルのスコープ内のみで有効な識別子を作ることができる。

```c++
namespace {
    struct data {...};
} /* unnamed-namespace */

// 同一ファイル内
data d;
```
### using namespace
名前空間に属するすべての識別子をその場で見えるようにする機能

```c++
namespace ns {
    void f();
    void g();
    void h();
} /* ns */

// using namespaceの例
using namespace ns;
f();
g();
h();
```

この機能は含まれる`すべて`の識別子を見えるようにする機能なので、
使わない識別子も見えるようになってしまったり、
名前が自分で作った識別子と被ってしまったりといろいろ危険なため使用はおすすめしない。

代わりに`using`を使うことで一部だけ`using namespace`したようにすることができる。

```c++
namespace ns {
    void f();
    void g();
    void h();
} /* ns */

// usingの例
using ns::f;
f();
ns::g();
ns::h();
```

### 名前空間で守るべきこと
#### グローバル名前空間を汚さない
C++では原則全ての識別子を名前空間に入れるべきである。
原則に合わない識別子は`main`関数とグローバルな`new`、`delete`演算子である。

#### 標準で予約されている名前空間に対して許可されていないことをしない
C++は`std`や`posix`など一部の名前空間が予約されている。
これらの名前空間は自分で標準ライブラリを作っているのでなければできるだけ追加しないほうが良い。

#### ヘッダファイルにusing namespaceやそれに準ずることをしない
名前空間は名前が被らないようにするための機能でもあるため、それを無効にしてしまうような使い方は避けるべきである。
ソースファイルであれば自分しか使わないかもしれないのである程度は許される。
しかし、ヘッダファイルはいろいろな人が使う可能性がある。
なので、ヘッダファイル内で`using namespace`を使ってしまうと識別子がかぶり、
`...が曖昧です`のようなエラーを他の開発者にも拡散してしまう可能性がある。

よって、ヘッダファイルでは特にこれらの機能の使用は避けるべきである。

## ムーブセマンティクス
C++11から導入された概念。
これまでコピーされていたデータを移動にすることで効率的に値の受け渡しが可能になる機能。

```
copy
+------+              +------+
| data | --- copy --> | data |
+------+              +------+

move
+- - - +              +------+
| data   --- move --> | data |
+ - - -+              +------+
```

上図はコピーとムーブを表したものである。
コピーは値すべてが別のインスタンスに`コピー`される。
ムーブは値のコピーではなく移動を行う。
値が移動されるのでムーブ元の変数はその後使える保証はない。

一般的にはムーブのコストはコピー以下になる。

## クラス
C++はクラスベースのオブジェクト指向言語なのでクラスを持つ。
C++のクラスはCの構造体に機能を追加することで実現している。

### アクセス修飾
C++はクラス内のメンバへのアクセスレベルとして3種類用意している。

| 修飾子 | 見えるところ |
|:------:|:-------------|
| private | 自クラス内から |
| protected | 自クラス内と継承[^1]したクラスから |
| public | どこからでも |

[^1]: 継承に関してはクラスセクションの中で説明する

C++にではstructはpublic、classはprivateがデフォルトのアクセス修飾になっている。

```c++
class klass {
private:
    int pri;
protected:
    int pro;
public:
    int pub;
};
```

### メンバ関数
C++はクラス内に関数を入れることができる。
メンバ関数もアクセス修飾の影響を受ける。

メンバ関数は大きく２つに分かれる。

+ 非静的メンバ関数
+ 静的メンバ関数

#### 非静的メンバ関数
一般的なメンバ関数の形。
普通に関数を宣言・定義するとこれが作られる。

非静的メンバ関数は暗黙的に自インスタンスへのポインタとして`this`が渡される。
インスタンスの非静的メンバへのアクセスはこの`this`を介して行われる。

```c++
struct klass {
    int value;

    int function() {
        return value; // this->valueとしなくても使うことができる
    }
};
```

データを変更しうるかしないかを示すことで、インスタンスが`const`が付いている時に呼び出せるかを決めることができる。

```c++
struct klass {
    int value;

    int get()const { // constをつけるとデータを変更しないことを明示できる
        return value;
    }

    void set(int v) {
        value = v;
    }
};

klass d;
d.get();
d.set(1);

const klass cd;
cd.get();
// cd.set(1); // constが付いているので呼び出せない
```

#### 静的メンバ関数
`static`をつけることで静的メンバにすることができる。

静的メンバ関数の場合はクラススコープに属する以外は一般的な非メンバ関数とほとんど同じように扱われる。

```c++
struct klass {
    static void function();
};
```

### コンストラクタ
C++はインスタンスを構築するための特別な関数としてコンストラクタをクラスに作ることができる。

コンストラクタは返り値の型を書かず関数名はクラスの名前を同じである。

```c++
struct klass {
    int a;

    klass(): a(2) {}
};
```

#### メンバ初期化リスト
コンストラクタはインスタンスの初期化時に呼ばれる関数である。
そのため、メンバを初期化する特別な構文が用意されている。

```c++
struct klass {
    int a, b, c;

    klass(int v) : a(v), b(), c() {}
};
```
コンストラクタに付いている`:`から`{}`までがメンバ初期化リストである。
各メンバ変数のコンストラクタをここで呼び出す。
コンストラクタ呼び出しであるため`()`の中にはコンストラクタに渡す引数を入れる。
`int`などのプリミティブ型もコンストラクタ呼び出しのように初期化する。

メンバ初期化リストの初期化順は`クラス内での宣言順`であって初期化リストに書いた順ではないので注意が必要である。

#### デフォルトコンストラクタ
引数無しでも呼ぶことができるコンストラクタをデフォルトコンストラクタと呼ぶ。
デフォルトの引数によって引数を渡す必要がない場合もデフォルトコンストラクタと呼ばれる。

```c++
class klass {
public:
    klass();
};
class klass2 {
public:
    klass(int a=0);
};
```

#### コピーコンストラクタ
自クラスへのconst参照を受けるコンストラクタをコピーコンストラクタと呼ぶ。

```c++
class klass {
public:
    klass(const klass&);
};
```

#### ムーブコンストラクタ
ムーブセマンティクスを実現するために右辺値参照が追加された。
自クラスへの右辺値参照を受けるコンストラクタをムーブコンストラクタと呼ぶ。

ムーブコンストラクタがムーブする処理を行うことで実際にムーブを行うことができる。

```c++
class klass {
public:
    klass(klass&&);
};
```

#### 変換コンストラクタ
引数がひとつで呼び出せるコンストラクタで`explicit`がついていないものを変換コンストラクタと呼ぶ。
変換コンストラクタは`=`で呼び出すことが可能である。

```c++
struct
class klass {
    klass(int);
    explicit klass(float);
};

klass k = 2;
// klass k = 3.14 // floatはexplicitが付いているので変換コンストラクタではない
```

### 継承
C++のようなクラスベースのオブジェクト指向言語では継承を使うことができる。

継承は継承元のクラスの内容をすべて引き継ぐ機能である。

継承にはアクセス修飾と同じく3種類存在する。

| 種類 | 動作 |
|:----:|:-----|
| public継承 | すべてのアクセス修飾をそのままに継承する |
| protected継承 | publicをprotectedにして継承する |
| private継承 | すべてprivateにして継承する |

デフォルトの継承はstructはpublic継承、classはprivate継承になる

## 仮想関数
C++ではメンバ関数に仮想関数という特殊な関数を作ることができる。
仮想関数は実行時まで呼び出す関数を決定しないことで動的なポリモーフィズムを実現できる機能である。

仮想関数を作る方法は簡単でメンバ関数の前に`virtual`をつけるだけである。

```c++
class klass {
public:
    virtual void vfunc();
};
```

仮想関数の力を発揮するには継承を使う必要がある。

```c++
struct base {
    virtual void vfunc() {
        std::cout<<"base vfunc"<<std::endl;
    }
    void func() {
        std::cout<<"base func"<<std::endl;
    }
};

struct derived : public base {
    void vfunc()override {
        std::cout<<"derived vfunc"<<std::endl;
    }
    void func() {
        std::cout<<"derived func"<<std::endl;
    }
};

derived der;
der.vfunc(); // derived vfunc
der.func(); // derived func

base& ba = der;
ba.vfunc(); // derived vfunc
ba.func(); // base func
```
この例では仮想関数として`vfunc`を定義、普通の関数として`func`を定義した。

普通にその変数の型で呼びだせばどの関数を使っても予想通りの結果になる。
しかし、基底クラスにキャストした場合は仮想関数でなければ基底クラスの関数が呼ばれてしまう。

この例の`derived::vfunc`のように基底クラスとは異なる動作を定義することをオーバーライドという。

基底クラスにキャストする可能性があるときにデストラクタを仮想関数にしなかった場合、
派生クラスのデストラクタが呼ばれない可能性があるため注意が必要である。

### 純粋仮想関数
仮想関数に定義を与えないようにすることで純粋仮想関数になる。

```c++
struct base {
    virtual void pvfunc() = 0;
};
```
この例のように`=0`を書くことで純粋仮想関数にすることができる。
純粋仮想関数は派生クラスで必ずオーバーライドしなければいけない。
純粋仮想関数を持つクラスは抽象クラスと呼ばれインスタンス化ができない。

### 仮想関数のオーバーヘッド
仮想関数は呼び出しに少しオーバーヘッドが存在する。
また、呼びだされうる仮想関数を配列化したテーブル(仮想関数テーブル(vtable))はバイナリに含まれるため、
少しだけバイナリが肥大化する可能性がある。

## 関数のdefault、delete指定
コンストラクタなどのコンパイラがデフォルトで作ってくれる関数を作らせたり、関数を削除したりすることができる機能。

```c++
struct data {
    data(const data&)=delete;
    data(data&&)=default;
    virtual ~data()=default;
};
```
上記の例ではコピーコンストラクタを削除し、
ムーブコンストラクタをコンパイラのデフォルト、
仮想デストラクタをデフォルトで作成した。


## 例外
C++は例外をサポートする。
例外は、何らかの異常事態の発生などを伝えるための機能。

一般的に例外は送出されると呼び出し元の関数の階層を戻る。
main関数を超えるとプログラムは異常終了する。

### throw
例外を発生させるための式がthrow式である。
throw式はその式が評価された時に例外を発生させる。

```c++
throw std::exception();
```

### catch
もしも、例外が送出されたときに何らかの処理を行いたいときはtry-catchを使うことで発生した例外を捕捉することができる。

```c++
try {
    throw std::exception();
}catch(std::exception& e) {
    // 1 std::exceptionなのでこちらが実行される
}catch(int) {
    // 2 std::exceptionはintではないので実行されない
}
```

このようにtry-catchの間で例外を発生させる可能性のある処理を行う。
例外が発生した場合はcatchで示した型に対応したブロックが実行される。

### 例外で投げれる型
C++は例外でどの値でも投げることができる。
つまり、`throw 1;`も正しく処理される。

しかし、何でも投げれることはコードを複雑にしてしまう可能性がある。
C++はstd::exceptionという例外用のクラスを用意している。
標準ライブラリが投げる例外はすべてこのstd::exceptionを継承したクラスである。

特に理由がなければ例外で投げる型はstd::exceptionの派生クラスであるべきである。

### noexcept
#### noexcept指定子
関数が例外を投げないことを示す指定子としてnoexcept指定子がある。

```c++
int get_zero()noexcept {
    return 0;
}
```
このようにnoexceptをつけることで例外を投げないことを明示できる。

noexceptは引数を取ることができ`noexcept(trueと評価される整数定数式)`の場合noexceptと同じ意味になる。
逆に`noexcept(falseと評価される整数定数式)`の場合例外を投げる可能性があることを示す。

また、delete演算子とデストラクタは明示しなかった場合noexcept(true)であるとみなされる。

noexcept(true)をつけた関数が例外を投げた場合std::terminate()が呼ばれプログラムが異常終了する。

#### noexcept演算子
引数に渡した式が例外を投げないかをtrueかfalseで返してくれる演算子。

引数に渡した式は実際に評価されない。

```c++
template<class T> void print(const T& v)noexcept(noexcept(v.print())) {
    v.print();
}
```
このように中で使う関数次第でnoexceptの指定を変えたい時に使われることが多い。

## テンプレート
いろいろなの型や値に対して同じ処理を行いたいときに使われる機能がテンプレートである。

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

// ===== 使う例 =====
add<int>(1, 2); // == 3
add(1, 2); // == 3 // 1, 2からintであると推論される。
add<std::string>("abc", "def"); // std::stringは+をオーバーロードしている
// add("abc", "def"); // "abc"と"def"からconst char[4]と推論される。 -> 配列は足し算できない
```
上記の例ではテンプレートを用い色々な型に対して`+`を行う処理を書いた。
この場合T型が`+`演算子を持たない場合コンパイルエラーになる。

上記の例より、引数から型が推論可能なときは省略ができる。

テンプレート引数には型だけではなく値も入れることができる。
値を入れる時の条件としてコンパイル時定数である必要がある。

```c++
template<int N> int square() {
    return N * N;
}

square<3>(); // == 9

int num = 3;
// square<num>(); // numはコンパイル時定数でない

constexpr int NUM = 3;
square<NUM>(); // == 9 // NUMはconstexprなのでコンパイル時定数

constexpr int get_number() {
    return 3;
}
square<get_number()>(); // == 9 // get_numberはconstexpr関数なのでコンパイル時定数が返る
```

## 型推論
C++11から追加された右辺値の値から左辺値の型を推論する機能である。

```c++
auto num = 1; // 1からnumはintと推論される
```
autoの推論規則はテンプレートの規則と同じである。

```c++
template<class T> void func(T);
func(1); // のTと
auto n = 1; // のautoは同じ型と推論される。

template<class T> void func(const T&);
func(n); // のTと
const auto& nn = n; // のautoは同じ型と推論される。
```

## ラムダ式
C++11からはその場で定義可能な即時関数としてラムダ式を使うことができる。

```c++
[]{
    return 1;
}
```
上記の例は1を返すだけのラムダ式である。

ラムダ式の仕様は結構多めなので省略した説明を行う。

```c++
[キャプチャリスト](引数リスト) -> 返り値の型 {関数の中身}
```

+ キャプチャリストは外側のローカル変数をラムダ式内でどう使うかを示す(省略不可)
+ 引数リストはラムダ式の仮引数(引数がない場合は省略可)
+ 返り値の型はラムダ式の返り値の型を書く(推論可能な場合は省略可(->も一緒に省略する))
+ 関数の中身はラムダ式が行う処理を記述する(省略不可)

よって、最小のラムダ式は`[]{}`となる。

### キャプチャリスト
ラムダ式のキャプチャの方法は2種類ある。

+ コピーキャプチャ
+ 参照キャプチャ

コピーキャプチャはローカル変数をコピーしラムダ式内で使用する。
参照キャプチャはローカル変数の参照をラムダ式内で使用する。

スレッドや非同期処理などラムダ式が実行される段階で、
関数のスコープが終了している可能性があるときはコピーキャプチャを使うべきある。

また、キャプチャしていないローカル変数はラムダ式内で使うことができない。

```c++
int a, b, c;

[a]{}; // aのみコピーキャプチャ
[a, b] {}; // a, bをコピーキャプチャ
[=] {}; // すべてのローカル変数をコピーキャプチャ

[&a]{}; // aのみ参照キャプチャ
[&a, &b]{}; // a, bを参照キャプチャ
[&]{}; // すべてのローカル変数を参照キャプチャ

[a, &b] {}; // aをコピーキャプチャし、bを参照キャプチャ
```

### ラムダ式の使い方
ラムダ式の実体は型名不明な関数オブジェクトである。

型名が不明なためautoで受ける。

```c++
auto lambda = []{};
```
また、関数オブジェクト・関数ポインタなどを統一的に扱えるクラスとして、
std::functionが存在しているのでこれを使うこともできる。

```c++
#include <functional> // std::functionは<functional>に入っている

std::function<void()> f = []{};
```

## イテレータ
C++ではデータを格納するコンテナとそれを扱うアルゴリズムがある。
コンテナではstd::vectorやstd::listなどがある。
アルゴリズムではstd::sortやstd::findなどがある。

このコンテナとアルゴリズムをつなぐものとしてイテレータが存在する。
イテレータにはいくつかのカテゴリが存在しており、それぞれのカテゴリで可能な操作が異なる。

### イテレータカテゴリ
+ InputIterator : 読み込みのみ、単方向移動
+ OutputIterator : 書き込みのみ、単方向移動
+ ForwardIterator : 読み書き、単方向移動
+ BidirectionalIterator : 読み書き、双方向移動
+ RandomAccessIterator : 読み書き、任意の要素への移動(ポインタはこれに含まれる)

図として表すと以下のようになる

```text
+---------------------------------+
|         RandomAccessIterator    |
+---------------------------------+
|        BidirectionalIterator    |
+---------------------------------+
|          ForwardIterator        |
+----------------+----------------+
|  InputIterator | OutputIterator |
+----------------+----------------+
```

イテレータは少なくとも`++`, `!=`, `==`, `*`(参照外し)ができる。
BidirectionalIteratorは追加で`--`が可能になる。
RandomAccessIteratorは更に追加で`+`(足し算), `-`(引き算)を使うことができる。

### イテレータの取り方
コンテナは`begin()`と`end()`メンバ関数を持っている。
このメンバ関数を呼び出すことでイテレータを取り出すことが可能である。
`begin()`はコンテナの先頭を指すイテレータを返し、`end()`はコンテナの末尾+1を指すイテレータを返す。

また、非メンバ関数として`std::begin`と`std::end`がある。
この関数はコンテナの場合`begin()`と`end()`をそれぞれ呼び出しそれを返す。
配列の場合、`std::begin`は先頭の要素を指すポインタを`std::end`は末尾+1を指すポインタを返す。

### イテレータの使い方
```c++
#include<vector>
#include<iostream>

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

for(auto itr = std::begin(vec); itr != std::end(vec); ++itr) {
    std::cout << *itr << std::endl;
}
```
上記の例では`std::vector`に格納した要素を表示していく例である。

```c++
#include<vector>
#include<algorithm> // std::sort

std::vector<int> vec = {1, 5, 3, 4, 8};

std::sort(std::begin(vec), std::end(vec));
```
上記の例はアルゴリズムの一つである`std::sort`を用い`std::vector`の要素をソートしている。