C99からC++14を駆け抜けるC++講座

# C++初心者Advent Calendar 2015
この記事は[C++初心者Advent Calendar 2015](http://www.adventar.org/calendars/922) 17日目の記事です
[<<9日目	｜Clang with Microsoft CodeGenがでたので試す](http://qiita.com/yumetodo/items/bd41f31f39dd590e8c80)
[<<16日目 | ブログズミ: Boost.Test v3 を使ってみた](http://srz-zumix.blogspot.jp/2015/12/boosttest-v3.html) || [18日目 | それC++なら#defineじゃなくてもできるよ | とさいぬの隠し部屋 >>](https://blog.myon.info/blog/2015-12-18/avoid-defining-macros/)

# はじめに

みなさま、ナマステ。さて、この記事のタイトルを見て、「時代・・・**サトウキビ**・・・[忍者](http://www.nicovideo.jp/user/5006073)・・・うぅ、頭が」となった人は私と趣味が似ています・・・って話はどうでもいいか。

よく、「C++はBetter Cとしてはじめればいい」みたいな話を聞くのでそれにそって一気にC++14まで駆け抜けようと思います。

ちなみにC99を知らない人はお断りです。さようなら。

でははじめますか。

しっかし書き終わってから思った。**なぜ複数の記事に分割しなかったし**
というわけで、超長文です。すみません。そのうち単独の記事も出します、きっと。

ところで、実はホッとしておりまして、なにかというと、前日のsrz-zumixさんの記事が**ちっとも初心者向けじゃない**んですよ。**初心者はBoostなんて使えません!!**
書き終わってから投稿に気が付いたんですが。この記事の後半は初心者向けじゃないなぁと思っていたのですが、それみて「**これよりは初心者向けだわー**」といった感じです。

個人的には、[歌舞伎座.tech #8 「C++初心者会」](https://ezoeryou.github.io/blog/article/2015-05-18-kabukiza-tech-8.html)とか見て以降、「初心者」が怖くなってしまっていましたが([初心者がBoost.asioをつかえるもんか！](http://www.shigemk2.com/entry/kbkz_tech.8.3))、さらに怖くなりました。初心者怖い。(srz-zumixさんすみません)

# =0で初期化をやめよう

## 0初期化は妥当か？

さて、初期化と聞くと

```c:C99
typedef struct {
  int a;
  int b;
} Hoge;
static int n;//static/thread_localな変数は0初期化される
int main(void)
{
  int foo = 0;//変数fooを0初期化
  Hoge hoge = { 0 };//変数hogeの最初のメンバ変数aを0で初期化、それ以外のメンバ変数(=メンバ変数b)をstatic変数と同じ方法で初期化(=0初期化)
  //略
  return 0;
}
```

みたいに、0初期化を浮かべる人が多いかもしれませんが、初期化はそれだけではありません。

そもそも**初期化とは、変数などの状態をプログラマにとって既知にすること**で、**断じて0にすることと同義ではありません**。どういうことでしょう？

```c:c99
#include <stdlib.h>
int main(void)
{
  int foo = 2;//変数fooを2で初期化
  int* n_p = malloc(sizeof(int));//変数n_pをmalloc関数で割り当てたメモリー領域へのポインタで初期化
  memset(n_p, 0xcc, sizeof(int));//変数n_pをmalloc関数で割り当てたメモリー領域を0xCCで全byte埋めて初期化
  free(n_p);
  return 0;
}
```

一般に初期化は、変数の読み出し操作の前に、変数の状態をプログラマーから既知にするために行います。static/thread_localな変数**以外**の変数は初期化子を書かない場合デフォルト初期化されますが、この時、クラス型ではないもしくは配列型で要素型がクラス型ではない変数(ex.)int型のような組み込み型やそのポインタ型のint*型、int[5]のような配列型)は**初期化が行われません(=値が不定)**。

値が不定だと困るので初期化子を書くわけですが、この時0初期化することが多いの、はxor命令に帰結させたりmemsetの呼び出しに最適化できたりするために一般に高速なためであって、なにも0でなくとも初期化には違いないわけです。

なお

```c:c99
typedef struct {
  int a;
  int b;
} Hoge;
int main(void)
{
  Hoge hoge;
  memset(&hoge, 0, sizeof(Hoge));
  return 0;
}
```

のようにするコードをたまに見かけますが、わざわざmemsetを自分で書かなくても

```c:c99
typedef struct {
  int a;
  int b;
} Hoge;
int main(void)
{
  Hoge hoge = { 0 };
  return 0;
}
```

で十分です。現代のコンパイラはmemsetの呼び出しに最適化できます。

またC++の場合は

```cpp:C++
struct Hoge {
  int a;
  int b;
};
int main()
{
  Hoge hoge = {};
  return 0;
}
```

で十分だったりします。

## =0で初期化できない例

=0と書く初期化は次のようなものです。

```c:c99
int main(void)
{
  int n = 0;
  return 0;
}
```

しかしこれはCなら構造体、C++ならクラスには適用できません

```c:c99
typedef struct {
  int a;
  int b;
} Hoge;
int main(void)
{
  //Hoge hoge = 0;//NG
  return 0;
}
```

## 0初期化するべきではない場面

memsetで0初期化もよく見かけます。これはどうでしょうか？

```c:c99
typedef struct {
  int a;
  int b;
} Hoge;
int main(void)
{
  Hoge hoge;
  int n;
  memset(&hoge, 0, sizeof(Hoge));
  memset(&n, 0, sizeof(int));
  return 0;
}
```

C99では問題ありませんでした。しかしC++にはクラスがあります。
ここで次のようなクラスを見てみましょう。

```cpp:C++14
#include <cstring>
#include <iostream>

#include "hexdumper.hpp"
class Hexa {
public:
    Hexa() : str_("arikitari") {}
    ~Hexa() = default;
    virtual void setStr(void){}
protected:
    char str_[0x10];
};

class Hexa2 : public Hexa {
public:
    Hexa2() : Hexa() {}
    ~Hexa2() = default;
    void setStr(void) noexcept override { std::strcpy(this->str_,"hexadrive"); }
    char* drawStr(void) noexcept { return this->str_; }
    const char* drawStr(void) const noexcept { return this->str_; }
};

int main(void)
{
    using std::endl;
    Hexa2 hexa = {};
    std::cout << "before memset" << endl << hexdump(hexa) << endl;
    Hexa2* pHexa = &hexa;
    std::memset(pHexa, 0, sizeof(Hexa2));
    std::cout << "after memset" << endl << hexdump(hexa) << endl;
    pHexa->setStr();	// ここでクラッシュする
    std::cout << pHexa->drawStr() << std::endl;
}
```

``hexdump``は自作関数です。

仮想関数がある派生クラスに対してmemsetを用いた例です。仮想関数である``setStr``は呼び出せず、手元の環境ではSegmentation faultしました。なぜでしょうか？

https://wandbox.org/permlink/0aoTnoyqgYaJd9Z6

```plain:実行結果
before memset
 Address | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 123456789ABCDEF
---------+-------------------------------------------------+----------------
00000000 | 00 19 40 00 00 00 00 00 61 72 69 6B 69 74 61 72 | .@.....arikitar
00000010 | 69 00 00 00 00 00 00 00                         | i.......

after memset
 Address | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 123456789ABCDEF
---------+-------------------------------------------------+----------------
00000000 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
00000010 | 00 00 00 00 00 00 00 00                         | ........

Segmentation fault
```

memsetの前後でclass変数を自作したhexdump関数でダンプしてみました。このコードの処理系では、仮想関数をvtableと呼ばれるもので実装しているようで(というかそれ以外の実装あるの？)、``00000000``～``00000007``の範囲がどうも該当しているようです。memsetによってこの部分が吹き飛ばされてしまうため、仮想関数である``setStr``の実行コードのあるアドレスが消え、結果としてヌルポしているようです。

また、コンストラクタでメンバ変数``str_``に与えた``arikitari``という文字列も吹き飛んでいます。せっかくデフォルトコンストラクタで初期化したのに、memsetで2重の初期化をしてしまっているわけです。

クラス変数の初期化memsetを使いたい場合は最低でもstandard-layout class(trivially copyable classである必要はあったっけ？)、一般にはPODクラスであるべきで、**PODとは何かがわからないうちは、memsetをクラス変数に使うのはご法度とおぼえておくべきです。**

- [本の虫: C++0xにおけるPODの定義](https://cpplover.blogspot.jp/2010/06/c0xpod.html)
- [C++の初期化は分かりにくい - ぷろみん](http://torini.hateblo.jp/entry/2015/03/08/C%2B%2B%E3%81%AE%E5%88%9D%E6%9C%9F%E5%8C%96%E3%81%AF%E5%88%86%E3%81%8B%E3%82%8A%E3%81%AB%E3%81%8F%E3%81%84)
- [Plain Old Data | 闇夜のC++](http://cpp.aquariuscode.com/plain-old-data)

## 統一初期化構文(Universal Initialization/Uniform Initialization)で初期化しよう
じゃあどうすればいいのでしょうか。

- [統一初期化・リスト初期化の見本帳 - イグトランスの頭の中](http://dev.activebasic.com/egtra/2015/12/02/845/)
- [波括弧の初期化があって嬉しいとき - イグトランスの頭の中](http://dev.activebasic.com/egtra/2015/12/03/847/)
- [aggregateと初期化リストの不思議 | 本の虫](http://cpplover.blogspot.jp/2010/09/aggregate.html)
- [多くのプログラマは言語を表面的な理解だけで使っている | 本の虫](http://cpplover.blogspot.jp/2010/09/blog-post_18.html)
- [initializer listの解説](http://cpplover.blogspot.jp/2010/03/initializer-list.html)
- [C++14の新機能: メンバー初期化子と初期化リストの組み合わせ | 本の虫](http://cpplover.blogspot.jp/2014/10/c14_2.html)
- [vector/arrayとUniform initialization+Initializer list - yohhoyの日記](http://d.hatena.ne.jp/yohhoy/20120724/p1)
- [C++11: Syntax and Feature#8.5 初期化子（Initializers）](http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#dcl.init)

はい、2日目、3日目でも解説がありましたし、本の虫にもありますね。統一初期化構文(Universal Initialization/Uniform Initialization)を使えばいいです。

```cpp:結論
std::pair<int, int> p3{};//OK
int hoge{};//OK
std::array<int, 4> arr{{}}
```
のようにかけます。

後述するtemplateと組み合わせて、任意の型をstatic storageと同じように初期化したいときとかは統一初期化構文一択だったりします。

まあしかし、実際の運用では常に使うというわけではなく、使うべきでない場面というのもあります。
[C++11 Universal Initialization は、いつでも使うべきなのか](http://qiita.com/h2suzuki/items/d033679afde821d04af8)
を読んでみると良いでしょう。

# std::coutとprintf

C++でなんか出力と言われたらやっぱり

```cpp:ありきたり
#include <iostream>
int main()
{
    std::cout << "arikitari_na_world!" << std::endl;
    return 0;
}
```

ですよね。なんでprintfが好まれないのか見ていきましょう。

そもそもprintfのプロトタイプ宣言は

```c:printf
int printf ( const char * format, ... );
```

ですね。

## format指定と型安全
例えば``stdint.h``/``cstdint``にある``int64_t``型を表示させたい場合、どうすればいいでしょうか？

```c:C99
#include <stdint.h>
#include <stdio.h>
int64_t num = 4288957324576;
//どっち？
printf("%lld", num);
printf("%I64d", num);
```

この2つを``#if``つかって分けるというコードを書かねばならないのでしょうか？
もちろんそんなことはなく、標準にそれをやってくれるマクロがあります。``#define __STDC_FORMAT_MACROS`` & ``#include <inttypes.h>`` (C99) / ``#include <cinttypes>`` (C++11) のマクロをつかって、

```c:コメントでもらったコード
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>

int64_t num = 4288957324576;
printf("%" PRId64, num);
```

こう書くことはできますが、文字列が(マクロで連結されますが)とぎれて見えます。これはなかなかみにくいんじゃないでしょうか(私見)。**ちなみに、文字列リテラルとマクロの間にスペースを入れ忘れると、C++11の機能であるUDLsと誤認されます**。

問題は**さらに深い**です。format指定することの利点は出力されるものがわかりやすいということになりますが、対応させるべき型が無限に存在する場合、**無限通りのformatが必要になります**。恐ろしや。STLに入っている型のうち対応させるべきものだけでもいくつあるんですかね、覚えられるか。

さらに型安全なものにしようとしたら、つまり、**format指定が適切かを調べコンパイルエラーにするには、どれだけ苦労しなければならないのでしょうか**。先のようなマクロもたくさん必要になります。

それでも型安全printfをつくるべく立ち向かう人たちは後を立ちません。

## 結論

```cpp
#include <iostream>
#include <cstdint>
#include <string>
int main()
{
    std::int64_t num = 4288957324576;
    std::size_t s = 32;
    std::string str = "arikitari";
    std::cout << num << ", " << s << ", " << str << std::endl;
    return 0;
}
```

templateが使えるおかげで、膨大な型全てに対応できました。formatがあるから面倒なんだ、という論法ですね。

ただし、iostreamいいぞ、という書き方をしましたが、正直に言うと設計が古すぎて、作り直すべきという声もC++聞こえてきます。

ああ、ちなみに[fmtlib/fmt](https://github.com/fmtlib/fmt)というライブラリがあって、高速かつC#に近いSyntaxで書けます。
[C++ Advent Calendar 2014](http://qiita.com/advent-calendar/2014/cpp)の17日目の記事である
[今年気になった C++ ライブラリとかフレームワークを紹介する記事 - はやくプログラムになりたい](http://rhysd.hatenablog.com/entry/2014/12/17/000053)
に紹介があります。2017/02/02現在も活発に開発されているようです。

```cpp:fmtlib/fmt
fmt::print("Hello, {}!", "world"); // => Hello, world!
std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
// s == "abracadabra"
```

# auto

いわゆる型推論ですね。[どこぞの](http://d.hatena.ne.jp/nowokay/20131224)[糞言語](http://cpplover.blogspot.jp/2009/11/java-7.html)[(Java)](http://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/type-inference-generic-instance-creation.html)を除けば、型推論は右辺の型から左辺の型を推測するものです。

```cpp
int num = 2;
auto re = 5 / num;//int型、2になる
```

組み込み型くらいはauto使わないほうがいいですが、``std::array::iterator``とか``std::vector<std::vector<int>>::iterator``とかわけわかめな長さの型が使われるので必須機能です。
あ、あとTMPする時・・・(ry

この辺はいなむ先生が、[C++アドベントカレンダー](http://www.adventar.org/calendars/926)12日目で
[C++のつまずきポイント解説](http://qiita.com/_EnumHack/items/a3724dead343b5aecb4e)
詳しく書いているので、少し難し目ですがぜひ読んでみてください。

# std::pair

さて、こいつはなにかと便利です。純粋に２つの変数をまとめるだけのものです

```c
typedef struct {
int first;
int second;
} PAIR;
```

みたいなものを二度と書かなくて良くなります。２つペアのものって多いですからね。座標とか、画像の大きさとかetc...

専用のクラスを書くまでもないときに重宝します。

[C++でマイナンバーのチェックデジットを計算する](http://qiita.com/yumetodo/items/600ca0df422010cbc4c1)
ここでは

```cpp:マイナンバー
#include <string>
#include <utility>
#include <numeric>
#include <stdexcept>
#include <cctype>
int calc_check_digit(const std::string& n) noexcept(false) {
    if (11 != n.size()) throw std::runtime_error("n.digit must be 11");
    const int r = std::accumulate(n.rbegin(), n.rend(), std::pair<int, int>{}, [](const auto& s, const char& e) -> std::pair<int, int>{
        if(!std::isdigit(e)) throw std::runtime_error("n.digit must be 11");
        return {s.first + (e - '0') * ((5 < s.second) ? s.second - 4 : s.second + 2), s.second + 1};
    }).first % 11;
    return (0 == r || 1 == r) ? 0 : 11 - r;
}
```

firstを合計、secoundをループカウントに使いました。

# std::array

配列です。説明は以上です。
・・・嘘です。

Cにも配列があって

```c
#include <stdio.h>
#include <stdlib.h>
#ifndef _countof
#define _countof( arr ) ( sizeof(arr) / sizeof(arr[0]))
#endif
int main()
{
	int arr[3] = { 3, 4, 2 };
	for(size_t i = 0; i < _countof(arr); ++i) printf("%d,", arr[i]);
	return 0;
}
```

こんなコードを書いたことはあると思います。ちなみにこれC++だと

```cpp
#include <iostream>
int main()
{
	int arr[3] = { 3, 4, 2 };
	for(auto it = std::begin(arr); it != std::end(arr); ++it) std::cout << *it << ", ";
	return 0;
}
```

こう書けます。``std::begin``と``std::end``が配列にも使えるんですね。

``std::array``を使うと

```cpp
#include <iostream>
#include <array>
int main()
{
	std::array<int, 3> arr = { 3, 4, 2 };
	for(auto it = arr.begin(); it != arr.end(); ++it) std::cout << *it << ", ";
	return 0;
}
```
で、Cの配列ではなく``std::array``を使うメリットは、

- ``back()``(最後の要素を取得)や``size()``(配列の大きさを取得)が使える
- **式中でポインタとみなされない**

式中でポインタとみなされないとはどういうこっちゃ？ですが、例えばCで要素型がint型の配列の全要素を表示する関数を作ることを考えてください。

```c:C版の配列全要素を表示関数
#include <stdio.h>
void array_print(const int * arr, size_t size)
{
    for(size_t i = 0; i < size; ++i) printf("%d, ", arr[i]);
}
```

Cでは御存知の通り、**配列は3つの例外を除き、常にポインタに読み替えられます**。3つの例外の1つは``sizeof``演算子を使う場合ですが、

```c
#include <stdio.h>
void f(int arr[])
{
    printf("%d", sizeof(arr));//arrはint*型
}
int main()
{
    int arr[5];
    printf("%d", sizeof(arr));//arrはint[5]型
    f(arr);
    return 0;
}
```

このように、要素数の型データが消えてしまうわけです。

C++を使えばもうすこしマシに書けます。

```cpp
#include <iostream>
#include <cstddef>
void f(const int (&arr)[5])
{
    std::cout << sizeof(arr);//arrはconst int (&)[5]型
}
int main()
{
    int arr[5];
    std::cout << sizeof(arr);//arrは//arrはint[5]型
    f(arr);
    return 0;
}
```

しかし、参照として渡されてもそれを取り回すのがわりと面倒です。また戻り値として指定できないことには代わりありません。

そこで``std::array``です。

```cpp
#include <iostream>
#include <array>
void f(const std::array<int, 5>& arr)
{
    std::cout << arr.size();
}
int main()
{
    std::array<int, 5> arr;
    std::cout << arr.size();
    f(arr);
    return 0;
}
```

すっきり。

Cを長くやっていた人なら、構造体のなかに配列のみをもたせたものを作った経験があるかもしれませんが、まさにそういう実装になっています。

なお``size()``は明日のmyon___氏が記事で書いてくれるかもしれませんが、``constexpr``関数なのでコンパイル時に値が決定します。どこぞの[陶芸家で中３女子](http://boleros.hateblo.jp/)な人が喜びそう。

# Range-based for

Range-based forとはCの配列と、``begin()``/``end()``メンバ関数をもつクラス型と(特殊な?)ADLで``begin()``/``end()``関数が見つかる型にのみ提供できるfor文です。いわゆるforeachですね。


```cpp:Range-based_for不使用
#include <iostream>
int main()
{
	int arr[3] = { 3, 4, 2 };
	for(auto it = std::begin(arr); it != std::end(arr); ++it) std::cout << *it << ", ";
	return 0;
}
```

これが

```cpp:Range-based_for使用
#include <iostream>
int main()
{
	int arr[3] = { 3, 4, 2 };
	for(auto&& e : arr) std::cout << e << ", ";
	return 0;
}
```

```cpp:Range-based_for不使用
#include <iostream>
#include <array>
int main()
{
	std::array<int, 3> arr = { 3, 4, 2 };
	for(auto it = arr.begin(); it != end(); ++it) std::cout << *it << ", ";
	return 0;
}
```

これが

```cpp:Range-based_for使用
#include <iostream>
#include <array>
int main()
{
	std::array<int, 3> arr = { 3, 4, 2 };
	for(auto&& e : arr) std::cout << e << ", ";
	return 0;
}
```

こう書けます。``auto&&``ってのはRange-based_forを使う際のおまじないです。ループ内でループ対象を書き換えないなら``const auto&``のほうがいいかもしれませんが、前者の方が**汎用的なのでよくわからない時は前者を使えばいい**と思います。おまじないの原理は
[range-based for loopsの要素の型について](http://qiita.com/rinse_/items/cdfce8aa6a685a8ebe0c)
とコメントを参照してください。この下で話すReferenceの種類と参照できるものが関係します。



# Reference

参照、と言ったほうが聞いたことがあるかもしれません。**Referenceとはすでにある値に対し別名をつける機能です。**
で、Referenceですが、大きくわけてlvalue referenceとrvalue referenceがあります。

で、この2つにどんな差があるのか、ですが、参照できるものの型を除けば**なにも違いはありません**。よくrvalue referenceはlvalue referenceと全く異なる、と考えて違いを考えすぎるあまり、わけわかめになる人がいますが、Referenceには違いないのです。

| 種類                              | 参照できるもの |
|-----------------------------------|----------------|
| lvalue reference(T&)              | lvalue         |
| const lvalue reference(const T&)  | **なんでも**   |
| rvalue reference (T&&)            | rvalue         |
| const rvalue reference(const T&&) | const rvalue   |

```cpp:Referenceの例
struct Test{
	int e;
};
const Test make_Test(){ return Test(); }
int main()
{
	int a = 0;
	const int b = 2;
	Test t;
	int& a_lr = a;
	const int& a_clr = a;//OK
	//int& b_lr = b;//NG
	const int& b_clr = b;//OK
	Test& t_lr = t;//OK
	Test&& t_rr = Test();//OK
	const Test& t_clr = Test();//OK
	const Test&& t_crr = make_Test();//OK
	const Test& t_clr = make_Test();//OK
	return 0;
}
```

という感じで、``const lvalue reference``が無双というか最強なので、rvalue referenceはあまり出番がありません。

## rvalue referenceをムーブに使う

追記: **さらに明快な解説を書きました**
[みんなlvalueとrvalueを難しく考えすぎちゃいないかい？](https://qiita.com/yumetodo/items/8eae5714a6cfe1c0407d)

さて、ざっとconstの有無を含めて4つのreferenceがあったわけですが、rvalue referenceに出番が無いかというとそんなことはありません。まあ他にもありますが、最も一般的な例であるrvalue referenceの用途、moveを紹介します。

実質的な機能は同じでも**型は違います**。また、それぞれ**優先順位があります**。ということは、関数のオーバーロードで型を変えれば呼び分けができるとうことです。
優先順位の詳細は
[const rvalue referenceは何に使えばいいのか - ここは匣](http://fimbul.hateblo.jp/entry/2013/12/22/015912)
を参照していただくとして、簡単な例を見ましょう。・・・クラスがなにかの説明は省きます。

```cpp:なんちゃってstringクラス
#include <cstring>
#include <cstddef>
#include <iostream>
class inferior_string
{
public:
	inferior_string() noexcept : m_s_(nullptr), m_len_(0), m_capacity_(0) {}
	inferior_string(const char* str)
	{
		const std::size_t len = (nullptr == str) ? 0 : std::strlen(str);
		if(0 == len){
			this->m_s_ = nullptr;
			this->m_len_ = this->m_capacity_ = 0;
		}
		else{
			const std::size_t cap = 2 * len;
			this->m_s_ = new char[cap]();
			std::memcpy(this->m_s_, str, len);//copy

			this->m_len_ = len;
			this->m_capacity_ = cap;
		}
	}
	inferior_string(const inferior_string& o)//copy constructor
	{
		if(0 == o.m_len_){
			this->m_s_ = nullptr;
			this->m_len_ = this->m_capacity_ = 0;
		}
		else{
			const std::size_t cap = o.m_len_ * 2;
			this->m_s_ = new char[cap]();
			std::memcpy(this->m_s_, o.m_s_, o.m_len_);//copy
			this->m_len_ = o.m_len_;
			this->m_capacity_ = cap;
		}
	}
	inferior_string(inferior_string&& o) noexcept
	: m_s_(o.m_s_), m_len_(o.m_len_), m_capacity_(o.m_capacity_)//move constructor
	{
		o.m_s_ = nullptr;//disable input object's destructor. DO NO FORGEET!!!
	}
	~inferior_string()
	{
		delete[] this->m_s_;
	}
	const char* c_str() const noexcept { return this->m_s_; }
private:
	char* m_s_;
	std::size_t m_len_;
	std::size_t m_capacity_;
};
std::ostream& operator<< (std::ostream& os, const inferior_string& str){
	os << str.c_str();
	return os;
}
int main()
{
	inferior_string str = "arikitari";
	inferior_string str2 = str;//copy constructor call
	std::cout << str << ", " << str2 << ", ";
	inferior_string str3 = std::move(str);//move constructor call
	//inferior_string str3 = static_cast<inferior_string&&>(str);//同じ意味
	std::cout << str3 << std::endl;
	return 0;

}
```
http://melpon.org/wandbox/permlink/Ame2XHIjS0oB0oLW

この場合、``const inferior_string&``より``inferior_string&&``のほうが、オーバーロードの優先順位が高いので、

```cpp
inferior_string str3 = static_cast<inferior_string&&>(str);
```

これはinferior_string&&を受け取る、move constructorが呼ばれます。ただし、このキャストを書くのはだるいので

```cpp
inferior_string str3 = std::move(str);
```

と書くのが一般的です。

こうしてみてわかったように、**断じてrvalue reference自体にはmove機能はありません**。たかが参照に一体何を求めてるのさ。

この辺もいなむ先生が、[C++アドベントカレンダー](http://www.adventar.org/calendars/926)12日目で
[C++のつまずきポイント解説](http://qiita.com/_EnumHack/items/a3724dead343b5aecb4e)
詳しく書いているので(ry

念の為に引用しておきます

>http://cpplover.blogspot.jp/2009/12/rvalue-reference.html
>std::move()を、何かコア言語の機能のように勘違いしていませんか？
あくまでSemanticsです。
std::moveは、static_cast(a)　をしているにすぎないのです。
rvalue referenceも、単なるreferenceに過ぎないのです。
Move Semanticsとは、たんにlvalueとrvalueを、movableなフラグとして使っているに過ぎないのです。

>その他は、lvalue referenceの場合と、何も変わりありません。
lvalue referenceで、データメンバにアクセスしたからと言って、そのオブジェクトがその後使えなくなるとは限らないでしょう。
もちろん、参照しているわけですから、publicなメンバ変数に対して、破壊的な書き換えもできるわけです。

**単にlvalueとrvalueを、movableなフラグとして使っているに過ぎない**んです。

# std::string

さきほどなんちゃって文字列クラスを作りましたが、ちゃんとC++には``std::string``があるのでそれを使いましょう。
**というかCで文字列操作するな、そういうことする言語じゃない！！**

```cpp
#include <iostream>
#include <string>
int main()
{
	using std::cout;
	using std::endl;
	std::string str1 = "arikitari_na_world!";
	cout << str1 << endl;
	str1.popback();//最後の一文字消去
	cout << str1 << endl;
	const auto str2 = str1.substr(0, str1.find_first_of('_'));//最初の'_'より前を抜き出し('_'は含めない)
	cout << str2 << endl;
	const auto str3 = str2 + "_toha";//文字列の連結
	cout << str3 << endl;
	return 0;
}
```

・・・まあこんな感じで使えます。例えばフルパスからファイル名だけほしい時は

```cpp
#include <iostream>
#include <string>
std::string get_n(const std::string& fullpath)
{
	return fullpath.substr(fullpath.find_last_of("\\/"), fullpath.find_last_of('.'));
}
int main()
{
	using std::cout;
	using std::endl;
	std::string str1 = "C:\\Users\\yumetodo\\OneDrive\\ドキュメント\\東京理科大\\物理学実験\\fit.log";
	cout << str1 << endl;
	cout << get_n(str1) << endl;
	return 0;
}
```

こんな感じですね。とっても楽。

**もっと初心者向け**な説明は
[22日目| C++の文字列処理関係と正規探索（未完）について - 水面下の夢](http://yumechi0525.hatenablog.com/entry/2015/12/23/004020)
へ。

# template入門

さきに「初心者にはtemplateなんて無理です」とか言ったのは誰でしょうね(私だ)。
大丈夫です、入門です。んなのまじめに解説したら本が一冊書けます。以下の解説より詳しく知りたい人は、
[C++関数テンプレートと半順序とオーバーロード](http://qiita.com/_EnumHack/items/cd904d383588ddb2189f)
を見てください。いなむ先生がなぜかプロ生ちゃんのAdventCalenderに投稿してます。

まあすでに出てきましたが。まずは定義から。

> テンプレートとは、コンパイル時に型や値を引数として渡す機能のことである。
>[14 テンプレート(Templates) | C++11の文法と機能(C++11: Syntax and Feature)](http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#temp)

分かった・・・？いい？**コンパイル時だよ？コンパイル時**。そこ大事だからね。

```cpp
#include <iostream>
template<typename T_>
constexpr const T_ & max(const T_& a, const T_& b)
{
    return (a > b)? a : b;
}
int main()
{
    const auto hoge1 = max(54, 23);//hoge1はint型
    const auto hoge2 = max<unsigned int>(54, 23);//hoge2はunsigned int型

    std::cout << hoge1 << hoge2 << std::endl;
    return 0;
}
```

みれば分かるように最大値を返す関数ですが、型が「T_」になってます。どういうことだってばよ？

これまで最大値を求める関数を作ろうと思ったら全部の型ごとに関数を書く必要が有りました。事実C言語のmath.hを見ると同じような機能の型が違う関数が乱造されています。んなもんいちいち覚えてらんないですよね？

そういった背景から(?)C++では関数をオーバーロード出来るようになりました。つまり、引数の型が異なれば同名の関数をいくつでも作れるようになりました。

2行目を見てください。templateから始まる部分がありますが、これがtemplateの仮引数と呼ばれるところです。関数にも仮引数があったけどあれに似てます。
ただし指定できるのは型名(とコンパイル時定数)のみです。
例えばこの場合新たにT_という型をでっち上げているわけですが、この時点では実際の型はわかりません。若干違いますが型の異なる関数が**無限に存在するイメージで差し支えありません**(但し、コンパイル時に確定します)。

7行目を見てください。これは[テンプレートの実引数推定(Template argument deduction)](http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#temp.expl.spec)という機能を使っています。
できるだけ普通のプログラマーの常識に合わせるために、とても複雑になっているのですが、逆に言えば、
ノリと勘と気分となんとなくでどーにかなるということです。
ようはtemplate関数の引数に書いた型に推論されるわけで。まあみればわかるでしょ。

8行目は[明示的なテンプレート実引数指定(explicit template argument specification)](http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#temp.fct.spec)と呼ばれていて、かっこ良く名前をつけましたがこの場合ならようはT_の型はunsigned intだよ～と教えているだけです。

7, 8行目のようにtemplateを使ったもの(今回はtempalte関数)を実際に読んでコンパイルされると、先ほどの「無限に存在する」状態の例えで言うならどれか特定のものに定まります。
もちろん実際に関数としてコンパイルされるのは呼び出されているものだけです(つまり使う場所と**同じ翻訳単位**にないとうまくいかない)。

# 初心者だってstd::enable_ifでSFINAEしたい

>[C++関数テンプレートと半順序とオーバーロード](http://qiita.com/_EnumHack/items/cd904d383588ddb2189f)
>SFINAEとは
Substitution Failure Is Not A Error
の略語である

知らんかったわ、まあそれはさておき。

テンプレートはどんな型でも受け取っていまいます。そのままだと**予期せぬ動作**をしたり、「[コンパイルエラーの爆発量を競う大会](http://faithandbrave.hateblo.jp/entry/2014/03/25/150659)」が開かれるほどのエラーメッセージがでます。
使える型を制約するにはどうしたら良いでしょうか？

## conceptの歴史(超要約)とC++1z(C++17)
ここでこの記事のタイトルを改めてみましょう。**「C99からC++14を駆け抜けるC++講座」**です。残念ながらC++1z(C++17)の機能は**紹介できない**わけです。

なんでこんなことを書くかというと、C++1zに**concept**なる機能が提案されています。もともとC++11で入るはずのものでしたが、
[Bjarne Stroustrup、Conceptと未来を語る | 本の虫](http://cpplover.blogspot.jp/2009/08/bjarne-stroustrupconcept_14.html)
にあるように、かなりいろいろあって結局入りませんでした。それからまもなく6年、再びconceptが提案されています。
[新機能"コンセプト"でC++1z時代のジェネリックプログラミング](http://qiita.com/_Nnwww/items/5a242466e94b2e432376)
早くほしいです。これから紹介するstd::enable_ifよりも直感的なはずですから。

追記:こんないい加減な説明より、**江添さんの
[帰ってきたコンセプト | Boost勉強会 \#16 大阪](http://ezoeryou.github.io/boost-benkyokai-oosaka-16/#/)
が数千倍わかりやすいです。**(岡山の陶芸家([@bolero_MURAKAMI](https://twitter.com/bolero_MURAKAMI))とでちまるさんの兄([@decimalbloat](https://twitter.com/decimalbloat))はワロタ)

しかし無いものは仕方ないです。std::enable_ifを紹介しましょう。

更に追記:どうもC++17に提案されていたconceptはrejectされたっぽい・・・？C++11でもさんざん揉めて入らなかったのにまた入らねーのかよ！

C++17の``if constexpr``とC++14の戻り値にautoを使う記法で少しましになりそうですが

[![C++ Weekly - Ep 18 C++17's constexpr if](http://img.youtube.com/vi/qHgM5UdzPQU/0.jpg)](http://www.youtube.com/watch?v=qHgM5UdzPQU)

```cpp:C++17
#include <type_traits>
template<typename T>
auto f(const T& a){
    if constexpr(std::is_integral_v<T>){
        return a + 1;
    }
    else if constexpr(std::is_floating_point_v<T>){
        return a + 0.1;
    }
    else {
        return a;
    }
}
int main(){
    using namespace std::literals;
    [[maybe_unused]] auto a1 = f(1);//result: 2(int)
    [[maybe_unused]] auto a2 = f(1.0);//result: 1.1(double)
    [[maybe_unused]] auto a3 = f("arikitari"s);//result: "arikitari"(std::string)
}
```

いや、conceptくれ。

## std::enable_if

``std::enable_if``なるものがありまして、これを使うとSFINAEを~~悪用~~利用した型制約templateを書けます。

いろいろ流儀がありますが、私は
[std::enable_ifを使ってオーバーロードする時、enablerを使う？](http://qiita.com/kazatsuyu/items/203584ef4cb8b9e52462)
の方法が好きなのでそれを紹介します。enablerを使わず、``std::nullptr_t``を使うといえば伝わる人には伝わるでしょう。

例えば、算術型(intとかdoubleとか)だけを受け取りたい場合を考えましょう。
まずは算術型か否かを判別する必要があります。
そういう時に活躍するのが**type_traits**ヘッダーです。ていうか``std::enable_if``もこれ**includeしないと使えません**。
で日本語より英語のサイトのほうがわかりやすいので
[\<type_traits> - C++ Reference](http://www.cplusplus.com/reference/type_traits/)
を見ながら話を進めます。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/94177/61a6529b-1f46-b888-cc43-1b4a8fcbdca8.png)

こんな風に書いてありますね。算術型はarithmeticって言うんですね・・・ってそうじゃない。
つまり``std::is_arithmetic``をつかえばいいと分かります。
[is_arithmetic - C++ Reference](http://www.cplusplus.com/reference/type_traits/is_arithmetic/)

```cpp
std::is_arithmetic<T>::value
```

これがtrueになる時、``T``は算術型ですね。

さて、であとは``std::enable_if``を書くだけですが、その前に**おまじない**を。``typename``って書くのはだるいので。

```cpp:alias_declarationでおまじない
namespace std{
    template<bool condition, typename T = void>
    using enable_if_t = typename std::enable_if<condition, T>::type;
}
```

``std::enable_if_t``ってのが標準にあるんですね。

では算術型のみ受け取る関数fを作ってみましよう。

```cpp
#include <iostream>
#include <type_traits>
template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, std::nullptr_t> = nullptr>
void f(T num)
{
    std::cout << "num:" << num << std::endl;
}
int main()
{
    f(3);
    //f("num");
    return 0;
}
```

http://melpon.org/wandbox/permlink/Dfn1NNNNR2lXaYlr

もしコメントアウトを外すと

```
prog.cc:12:5: error: no matching function for call to 'f'
    f("num");
    ^
prog.cc:3:48: note: candidate template ignored: disabled by 'enable_if' [with T = const char *]
using enable_if_type = typename std::enable_if<condition, T>::type;
                                               ^
1 error generated.
```

のように**コンパイルエラーになります。やったぜ！**

さて、ここからがSFINAEの出番です。

```cpp
#include <iostream>
#include <type_traits>
template<typename T> struct is_char_type : public std::false_type {};
template<typename T> struct is_char_type<T const> : public type_traits::is_char_type<T> {};
template<typename T> struct is_char_type<T volatile> : public type_traits::is_char_type<T> {};
template<typename T> struct is_char_type<T const volatile> : public type_traits::is_char_type<T> {};
template<> struct is_char_type<char> : public std::true_type {};
template<> struct is_char_type<wchar_t> : public std::true_type	{};
template<> struct is_char_type<char16_t> : public std::true_type {};
template<> struct is_char_type<char32_t> : public std::true_type {};
template<typename T, std::enable_if_t<std::is_arithmetic<T>::value, std::nullptr_t> = nullptr>
void f(T num)
{
    std::cout << "num:" << num << std::endl;
}
template<typename T, std::enable_if_t<is_char_type<T>::value, std::nullptr_t> = nullptr>
void f(const T* s)
{
    std::cout << "str:" << s << std::endl;
}
int main()
{
    f(3);
    f("num");
    return 0;
}
```

こんな風に文字列へのポインタを受け取るオーバーロードを追加しました。
もしSFINAEがないと``f(3)``という呼び出しはコンパイルエラーになります。なぜならば、オーバーロード解決のためにまずfという名前の関数を捜索し、2つ見つかるわけですが、下のほうのfが呼べるかを調べるときにエラーになるからです。
SFINAEはこのエラーを**とりあえず無視(=オーバーロード候補から外す)**ので関数が一つに定まり、呼び分けができるわけです。

ちなみにC++03でも仕様が曖昧だっただけで使えたコンパイラもあったらしいです
[任意の式によるSFINAE - cpprefjp C++日本語リファレンス](http://cpprefjp.github.io/lang/cpp11/sfinae_expressions.html)

まとめると、``型名T``に制約を書ける場合は

```cpp
template<typename T, std::enable_if_t<許可条件(trueで有効), std::nullptr_t> = nullptr>
```

のように書けばいいということになります。


実際にこれを使って、2次元のpointクラスを作ってみたものがこちらになります。
https://github.com/Nagarei/DxLibEx/blob/master/dxlibex/basic_types/point2d.hpp#L72

型制約をかけただけではSFINAEは使っていません、オーバーロード解決の際の候補から外すことがSFINAEです、念のため

# templateでif

もはや初心者とは何だったのかという内容ですが、さわりだけ。
結論から言うと、C++11で``std::conditional``が入りまして、まんまIFなので、**それ使えばいいです**

[メモ：std::conditionalでif～else if～elseみたいなことをしようとすると見づらい](http://qiita.com/kazatsuyu/items/f8c3b304e7f8b35263d8)
[C++0x std::conditional - Faith and Brave - C++で遊ぼう](http://faithandbrave.hateblo.jp/entry/20100510/1273473979)

```cpp
//C++11 or later
using c_type = typename std::conditional<[(コンパイル時に評価できる)条件式], [真の時の型], [偽の時の型]>::type;
//C++14 or later
using c_type = std::conditional_t<[(コンパイル時に評価できる)条件式], [真の時の型], [偽の時の型]>;
```

のように書けまして、

[Variadic Template を使って switch を使ったテンプレート関数呼び出しを除去する](http://qiita.com/adatchey/items/7d721f7670c4cd8f8af0)
[C++ Advent Calendar 2015](http://www.adventar.org/calendars/926)の2日目の記事ですがこんな具合に~~悪用~~利用できます

ですが**原理**を説明しましょう。

```cpp
#include <type_traits>
template <bool Con, class Then, class Else>//(2, 3, 4)
struct IF;//(1)
template <class Then, class Else>//(5)
struct IF<true, Then, Else> {//(6)template第一引数がtrueの時はこの定義
    typedef Then type;//(7, 8, 12)
};
template <class Then, class Else>//(5)
struct IF<false, Then, Else> {//(6)template第一引数がfalseの時はこの定義
    typedef Else type;//(7, 9, 15)
};

//中略
using type1 = typename IF<true, int, double>::type;//int型になる(10, 11, 13)
using type2 = typename IF<false, int, double>::type;//double型になる(10, 14, 16)
```

**まるで暗号のようだ**という声が聞こえてきそうです。一つ一つ説明します。

1. まず、``IF``というクラス(structと書いてあるので原則public指定)があります。
2. こいつはtemplateクラスです。
3. このクラスのtemplate引数は3つです
4. 一つ目は``bool``型、2つめと3つめは**型名**です
5. 2つのtemplate特殊化があります
6. template第1引数が**trueの時とfalseの時**です
7. 2つのtemplate特殊化では**どちらでも型名typeがtypedefされます**
8. template第1引数がtrueの時、**型名typeはtemplate第2引数の別名**となります。
9. template第1引数がfalseの時、**型名typeはtemplate第3引数の別名**となります。
10. このクラスを使ってみます。
11. template第1実引数にtrueが指定されました
12. 型名typeはtemplate第2実引数の別名になるのでint型になります
13. それの別名として``type1``という新たな型を定義するので、``type1``はint型です
14. template第1実引数にfalseが指定されました
15. 型名typeはtemplate第3実引数の別名になるのでdouble型になります
16. それの別名として``type2``という新たな型を定義するので、``type2``はdouble型です

説明とコード中の()の数字を対応させながら読んでみてください。

で、今回trueとかfalseとかやってたところはもちろん、``std::is_arithmetic``とか、とにかく**コンパイル時に値が決まれば**指定できます。

# templateをつかって入力関数を作ってみよう

追記
**単体の記事にしました**
http://qiita.com/yumetodo/items/2a1d5f855bae6d100658

# License

[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja)

<a href="https://commons.wikimedia.org/wiki/File:CC-BY_icon.svg#/media/File:CC-BY_icon.svg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/CC-BY_icon.svg/1200px-CC-BY_icon.svg.png" alt="CC-BY icon.svg" width="88px"></a>

# C++初心者Advent Calendar 2015
この記事は[C++初心者Advent Calendar 2015](http://www.adventar.org/calendars/922) 17日目の記事です
[<<9日目	｜Clang with Microsoft CodeGenがでたので試す](http://qiita.com/yumetodo/items/bd41f31f39dd590e8c80)
[<<16日目 | ブログズミ: Boost.Test v3 を使ってみた](http://srz-zumix.blogspot.jp/2015/12/boosttest-v3.html) || [18日目 | それC++なら#defineじゃなくてもできるよ | とさいぬの隠し部屋 >>](https://blog.myon.info/blog/2015-12-18/avoid-defining-macros/)

次は18日目、myon___さんの「それ #define じゃなくてもできるよ」ですね。constexprとか出るのかな~~(きっと出ない)~~と思ったら触りだけでた