Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C++17の新機能 落穂拾い / new features of C++17 - gleaner

C++17の新機能 落穂拾い / new features of C++17 - gleaner

C++17 で追加されたライブラリ機能の紹介です。

一応調べながら書いてはいますが、力量の問題でいろいろ間違ってるかもです。
相変らず使用例が無いのは単なる力不足です…

Miutsuru kariya

March 28, 2019
Tweet

More Decks by Miutsuru kariya

Other Decks in Programming

Transcript

  1. 0

  2. *this のコピーキャプチャ 3 P0018R0 : Lambda Capture of *this by

    Value http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r0.html P0018R1 : Lambda Capture of *this by Value http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0018r1.html P0018R2 : Lambda Capture of *this by Value as [=,*this] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0018r2.html P0018R3 : Lambda Capture of *this by Value as [=,*this] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0018r3.html
  3. *this のコピーキャプチャ 導入の背景 6 今までの問題点 • デフォルトコピーキャプチャを使うと、さもコピーキャプ チャされてる風に(?)メンバ変数名だけでアクセス可能 になるが、実際には this

    ポインタがコピーされてるだけな ので、メンバ変数は実質参照キャプチャになっている。 • *this をコピーキャプチャするには初期化キャプチャを使 用して別の変数を導入する必要がある。 • デフォルトコピーキャプチャと *this からの初期化キャプ チャを両方使用しても、間違ってメンバ変数名単体でアク セスすると参照アクセスになってしまう。
  4. *this のコピーキャプチャ 導入の背景 7 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ UB!!! デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ
  5. *this のコピーキャプチャ 導入の背景 8 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [self = *this]{ return self.i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } ナゾの変数 self を導入して、 無理やりコピーキャプチャに。 でもアクセスが面倒… ナゾの変数 self を導入して、 無理やりコピーキャプチャに。 でもアクセスが面倒…
  6. *this のコピーキャプチャ 導入の背景 9 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=, self = *this]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ UB!!! デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ せっかくナゾの変数 self を導入して も、デフォルトコピーキャプチャしてい ると this 経由でアクセスできちゃう…
  7. *this のコピーキャプチャ 対応 12 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [*this]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } ナゾの変数 self を導入して、 無理やりコピーキャプチャに。 でもアクセスが面倒… ラムダキャプチャに *this を指定すると *this がコピーキャプチャされる。 アクセスも簡単!
  8. *this のコピーキャプチャ 対応 13 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=, *this]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } ナゾの変数 self を導入して、 無理やりコピーキャプチャに。 でもアクセスが面倒… デフォルトコピーキャプチャと一緒に 使っても大丈夫!
  9. *this のコピーキャプチャ 対応 14 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [&, *this]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } ナゾの変数 self を導入して、 無理やりコピーキャプチャに。 でもアクセスが面倒… もちろん、デフォルト参照キャプチャと 一緒に使っても大丈夫!
  10. *this のコピーキャプチャ 悲報 16 • デフォルトコピーキャプチャでメンバ変数が実質 参照キャプチャになるのは変わってない。 • C++20 でデフォルトコピーキャプチャで

    this をコ ピーキャプチャする挙動が非推奨になるが、 C++17 ではまだデフォルトコピーキャプチャ指定 時に this を指定できない。
  11. *this のコピーキャプチャ 悲報 17 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=]{ return i; }; } }; int main() { auto l = S(42).f(); std::cout << l() << '¥n'; } デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ UB!!! デフォルトコピーキャプチャだけだと、 今までと何も変わってない…
  12. *this のコピーキャプチャ 悲報 18 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=]{ return i; }; } }; int main() { auto s = S(42); auto l = s.f(); std::cout << l() << '¥n'; } デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ C++20 だと デフォルトコピーキャプチャだけで this にアクセスするのは非推奨…
  13. *this のコピーキャプチャ 悲報 19 #include <iostream> struct S { S(int

    i) : i(i) {} int i; auto f() { return [=, this]{ return i; }; } }; int main() { auto s = S(42); auto l = s.f(); std::cout << l() << '¥n'; } デフォルトコピーキャプチャでも、 メンバ変数は this 経由でのアクセス なので、実質参照キャプチャ C++20 からは このように書くのが良いが、 C++17 ではこの書き方はエラー
  14. emplace の戻り値型変更 23 P0084R0 Emplace Return Type http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0084r0.pdf P0084R1 Emplace

    Return Type (Revision 1) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0084r1.pdf P0084R2 Emplace Return Type (Revision 2) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0084r2.pdf
  15. emplace の戻り値型変更 導入の背景 26 ペーパーに載ってた例 // ① 格納してすぐにメンバ関数呼び出し my_container.emplace_back(…); my_container.back().do_something(…);

    // ② 格納してすぐに関数に引き渡し(バンドじゃないよ(分かったらおっさん my_container.emplace_back(…); do_something_else(my_container.back()); // ➂ デフォルト構築してすぐにファイルから読み込み my_container.emplace_back(); my_container.back().read(file_stream);
  16. emplace の戻り値型変更 対応 30 ペーパーに載ってた例(改) // ① 格納してすぐにメンバ関数呼び出し my_container.emplace_back(…).do_something(…); //

    ② 格納してすぐに関数に引き渡し do_something_else(my_container.emplace_back(…)); // ➂ デフォルト構築してすぐにファイルから読み込み my_container.emplace_back().read(file_stream);
  17. emplace の戻り値型変更 対応 32 下記の2点がよくわかりませんでした… • 他の emplace 系の戻り値型は iterator

    な のに何で参照なの? • 何で std::priority_queue::emplace は対象 外なの? 教えて!エロい人!!!
  18. 単純な文字列変換 35 N4412: Shortcomings of iostreams http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4412.html P0067R0: Elementary string

    conversions http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0067r0.html P0067R1: Elementary string conversions, revision 1 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r1.html P0067R2: Elementary string conversions, revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r2.html P0067R3: Elementary string conversions, revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r3.html P0067R4: Elementary string conversions, revision 4 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r4.html P0067R5: Elementary string conversions, revision 5 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0067r5.html
  19. 単純な文字列変換 導入の背景 37 既存ライブラリの問題点 • 書式指定文字列うぜぇ • 動的メモリ割当強制うぜぇ • ロケールうぜぇ

    • 仮想関数呼び出しうぜぇ • バッファオーバーラン怖ぇ • 入力文字列のエラー分かんねぇのうぜぇ • 入力文字列のスペース勝手に無視すんのうぜぇ • 頭の0x勝手に解釈すんのうぜぇ
  20. 単純な文字列変換 導入の背景 39 既存機能 うぜぇとこ sprintf ロケール、書式指定文字列、バッファオーバーラン snprintf ロケール、書式指定文字列 sscanf

    ロケール、書式指定文字列 atol ロケール、エラー発生不明 strtol ロケール、空白無視、0x勝手に解釈 strstream ロケール、空白無視 stringstream ロケール、空白無視、動的メモリ割当 num_put / num_get facets ロケール、仮想関数呼び出し to_string ロケール、動的メモリ割当 stoi etc. ロケール、動的メモリ割当、空白無視、0x勝手に解釈、 エラー時例外
  21. 単純な文字列変換 対応 43 新規ライブラリの特徴 • 書式指定は文字列じゃない • 動的メモリ割当しない • ロケール無視

    • 仮想関数呼び出ししない • バッファオーバーランしない • 戻り値でエラー返す • 入力文字列のスペース無視しない • 頭の0x解釈しない
  22. 単純な文字列変換 対応 44 文字列から数値への変換 from_chars_result from_chars(const char* first, const char*

    last, INT※1& value, int base = 10); from_chars_result from_chars(const char* first, const char* last, FLOAT※2& value, chars_format fmt = chars_format::general); ※1 符号付き整数型、符号無し整数型、charのいずれか。 整数型全部じゃないよ。(bool とか char32_t とかは無い) ※2 任意の浮動小数点型。
  23. 単純な文字列変換 対応 45 文字列から数値への変換 struct from_chars_result { const char* ptr;

    //数値として解釈できない文字へのポインタ errc ec; //変換失敗した場合のエラーコード }; enum class chars_format { scientific = 値は未規定, // %e と同じ fixed = 値は未規定, // %f と同じ hex = 値は未規定, // %a とだいたい同じ general = fixed | scientific // %g と同じ };
  24. 単純な文字列変換 対応 46 数値から文字列への変換 to_chars_result to_chars(char* first, char* last, INT※1

    value, int base = 10); to_chars_result to_chars(char* first, char* last, FLOAT※2 value); to_chars_result to_chars(char* first, char* last, FLOAT※2 value, chars_format fmt); to_chars_result to_chars(char* first, char* last, FLOAT※2 value, chars_format fmt, int precision);
  25. 単純な文字列変換 対応 47 数値から文字列への変換 struct to_chars_result { char* ptr; //

    出力された最後の文字の次へのポインタ errc ec; // 変換失敗した場合のエラーコード };
  26. 単純な文字列変換 使い方 50 // 文字⇒数値変換 const char s[] = "42kg";

    int i = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, i); assert(i == 42); assert(r.ptr == s + 2); assert(r.ec == std::errc{}); ※ r.ptr は数値として解釈できない文字(この場合は"k")を指す。 (エラーではない) ちなみに、ここでは説明のため敢えて r で受けてるけど普通は構造化束縛使うよね…
  27. 単純な文字列変換 使い方 51 // マイナス符号 const char s[] = "-42g";

    int i = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, i); assert(i == -42); assert(r.ptr == s + 3); assert(r.ec == std::errc{});
  28. 単純な文字列変換 使い方 52 // プラス符号はNG const char s[] = "+42";

    int i = 114'514; auto r = std::from_chars(s, s + sizeof(s) - 1, i); assert(i == 114'514); assert(r.ptr == s); assert(r.ec == std::errc::invalid_argument); ※ エラーの時は i は変わらず、r.ptr は数値として解釈できない文 字(この場合は"+")を指す。
  29. 単純な文字列変換 使い方 53 // 数値がデカすぎる場合もNG const char s[] = "12345678901234567890";

    int i = 42; auto r = std::from_chars(s, s + sizeof(s) - 1, i); assert(i == 42); assert(r.ptr == s + sizeof(s) - 1); assert(r.ec == std::errc::result_out_of_range); ※ この場合も、r.ptr は数値として解釈できない文字を指すので、最 後の数字の次の文字(つまり終端)を指している。 (変換対象の文字の次ではない)
  30. 単純な文字列変換 使い方 54 // もちろん16進数はOK const char s[] = "DEADBEEF";

    int i = 42; auto r = std::from_chars(s, s + sizeof(s) - 1, i, 16); assert(i == 0xDEAD'BEEF); assert(r.ptr == s + 8); assert(r.ec == std::errc{});
  31. 単純な文字列変換 使い方 55 // 16進数でも頭の"0x"はNG const char s[] = "0xDEADBEEF";

    int i = 42; auto r = std::from_chars(s, s + sizeof(s) - 1, i, 16); assert(i == 0); assert(r.ptr == s + 1); assert(r.ec == std::errc{}); ※ エラーじゃなくて、先頭の0だけ変換されてる。(わりとワナ)
  32. 単純な文字列変換 使い方 56 // ナゾの36進数までOK const char s[] = "1Z1z";

    int i = 42; auto r = std::from_chars(s, s + sizeof(s) - 1, i, 36); assert(i == 92'087); assert(r.ptr == s + 4); assert(r.ec == std::errc{});
  33. 単純な文字列変換 使い方 57 // 浮動小数点型 const char s[] = "42.195km";

    double d = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, d); assert(d == 42.195); assert(r.ptr == s + 6); assert(r.ec == std::errc{});
  34. 単純な文字列変換 使い方 58 // 浮動小数点型もプラス符号はNG const char s[] = "+42.195km";

    double d = 114'514; auto r = std::from_chars(s, s + sizeof(s) - 1, d); assert(d == 114'514); assert(r.ptr == s); assert(r.ec == std::errc::invalid_argument);
  35. 単純な文字列変換 使い方 59 // 指数部のプラス符号はOK(もちろんなくてもOK) const char s[] = "2.99792458e+8m/s";

    double d = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, d); assert(d == 2.997'924'58e+8); assert(r.ptr == s + 13); assert(r.ec == std::errc{});
  36. 単純な文字列変換 使い方 60 // fmtがscientificの場合は指数部が無いとNG const char s[] = "299792458m/s";

    double d = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, d, std::chars_format::scientific); assert(d == 0); assert(r.ptr == s); assert(r.ec == std::errc::invalid_argument); ※ 形式エラーの場合は ptr は先頭を指すらしい。(たぶん使わない)
  37. 単純な文字列変換 使い方 61 // fmtがhexならみんな大好き16進浮動小数点も行けるけど、 // こちらも先頭の0xはNG const char s[]

    = "CAFE.BABEp+15Java"; double d = 0; auto r = std::from_chars(s, s + sizeof(s) - 1, d, std::chars_format::hex); assert(d == 0xCAFE.BABEp+15); //つまり、1.702'845'791e+9 assert(r.ptr == s + 13); assert(r.ec == std::errc{});
  38. 単純な文字列変換 使い方 62 // 数値⇒文字変換 int i = 42; char

    s[10]; auto r = std::to_chars(s, s + sizeof(s), i); assert("42"sv == std::string_view(s, r.ptr - s)); assert(r.ec == std::errc{}); ※ プラス符号は付かない。(付ける方法は無い) 出力は '¥0' で終端されるわけではないので注意!
  39. 単純な文字列変換 使い方 63 // もちろん16進数もOK int i = 42; char

    s[10]; auto r = std::to_chars(s, s + sizeof(s), i, 16); assert("2a"sv == std::string_view(s, r.ptr - s)); assert(r.ec == std::errc{}); ※ 頭に"0x"は付かない。(付ける方法は無い) 英文字の出力は小文字。(大文字バージョンは無い)
  40. 単純な文字列変換 使い方 64 // もちろん(?)ナゾの36進数まで行ける int i = 92'087; char

    s[10]; auto r = std::to_chars(s, s + sizeof(s), i, 36); assert("1z1z"sv == std::string_view(s, r.ptr - s)); assert(r.ec == std::errc{});
  41. 単純な文字列変換 使い方 65 // バッファが足りないとエラー int i = 114'514; char

    s[5]; auto r = std::to_chars(s, s + sizeof(s), i); assert(r.ptr == s + sizeof(s)); assert(r.ec == std::errc::value_too_large); ※ 変換エラーの場合は ptr は最後を指すらしい。(たぶん使わない) 変換エラーの場合、バッファの中身は未規定
  42. 単純な文字列変換 使い方 66 // 浮動小数点 double d = 100'000; char

    s[10]; auto r = std::to_chars(s, s + sizeof(s), d); assert(r.ec == std::errc{}); assert("1e+05"sv == std::string_view(s, r.ptr - s)); ※ フォーマットを指定しないと、ロケール C の printf で %f と %e で変換した場合に文字列が短くなる方になる。 同じ長さの場合には %f 優先。 printf の %g とは違うので注意。
  43. 単純な文字列変換 使い方 67 // 浮動小数点 double d1 = 3.141592653589793238462643383279; char

    s[50]; auto r1 = std::to_chars(s, s + sizeof(s), d1); assert(r1.ec == std::errc{}); double d2 = 0; auto r2 = std::from_chars(s, r1.ptr, d2); assert(d1 == d2); assert(r2.ec == std::errc{}); ※ 浮動小数点数は、文字列化の際に精度を指定しない場合、ラウンド トリップして結果が等しくなるように処理される。 フォーマットを指定した場合でも同じ。(ここも printf と違う)
  44. 単純な文字列変換 使い方 68 // 浮動小数点 double d = 3.141592653589793238462643383279; char

    s[100]; auto r = std::to_chars(s, s + sizeof(s), d, std::chars_format::general, 3); assert(r.ec == std::errc{}); assert("3.14"sv == std::string_view(s, r.ptr - s)); ※ 精度の指定内容は printf の対応する書式と同じ。 (精度の指定はできるけど幅の指定はできないよ)
  45. 単純な文字列変換 使い方 69 // みんな大好き16進浮動小数点もOK double d = 0.0625; char

    s[10]; auto r = std::to_chars(s, s + sizeof(s), d, std::chars_format::hex); assert(r.ec == std::errc{}); assert("1p-04"sv == std::string_view(s, r.ptr - s)); ※ 頭に0xは付かない。
  46. 単純な文字列変換 悲報 72 何と VC++ 14.16 は 浮動小数点数も それなりに 対応してる!

    すごいぞ VC++! まだ不完全ではあるけど、ちょっと見直した…
  47. 検索アルゴリズム 75 N3411: Additional Searching Algorithms http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3411.pdf N3606: Extending std::search

    to use Additional Searching Algorithms http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3606.html N3703: Extending std::search to use Additional Searching Algorithms (Version 3) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3703.html P0253R0: Fixing a design mistake in the searchers interface in Library Fundamentals http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0253r0.pdf P0253R1: Fixing a design mistake in the searchers interface in Library Fundamentals http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0253r1.pdf
  48. 検索アルゴリズム 導入の背景 82 template<class ForwardIterator1, class ForwardIterator2> ForwardIterator1 search(ForwardIterator1 first1,

    ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> ForwardIterator1 search(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred); ※ [first1, last1) が検索される範囲、[first2, last2) が検索パ ターン範囲なので、前処理結果を保存できる余地が無さそう…
  49. 検索アルゴリズム 対応 87 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n';
  50. 検索アルゴリズム 対応 88 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n'; 検索パターン範囲をッ、コンストラクタの引数 にしてッ、検索オブジェクトを作るッ!!! ※ ここでは Boyer-Moore アルゴリズム
  51. 検索アルゴリズム 対応 89 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n'; 検索対象範囲をッ、関数呼び出し演算子の引数に してッ、実際に検索するッ!!! 同じオブジェクトで何度でも検索できるぞッ!!!
  52. 検索アルゴリズム 対応 90 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n'; 検索結果はッ、見つかった場所の最初と最後(+1) がッ、イテレータのペアで返ってくるッ!!! ※ 見つからなかったらどっちも検索対象範囲の最後
  53. 検索アルゴリズム 対応 91 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n'; 上記の場合、「柿」は10文字目なので、出力は「30, 33」になる。 (文字列リテラルがUTF-8なので1文字3バイトである事に注意!)
  54. 検索アルゴリズム 対応 92 使い方イメージ auto s = u8"柿"sv; auto bm

    = std::boyer_moore_searcher(begin(s), end(s)); auto t = u8"杮杮杮杮杮杮杮杮杮杮柿杮杮杮杮杮杮杮杮杮杮"sv; auto p = bm(begin(t), end(t)); std::cout << p.first - begin(t) << ", " << p.second - begin(t) << '¥n'; 上記の場合、「柿」は10文字目なので、出力は「30, 33」になる。 (文字列リテラルがUTF-8なので1文字3バイトである事に注意!) あ、「柿」(かき)はこの文字だけで、あとは「杮」(こけら)です。 見ればわかると思うけど(?)、念のため。
  55. 検索アルゴリズム 検索オブジェクトの種類 95 デフォルト 愚直に検索。(今までの std::search と同じ※) 前処理しないので、検索パターンや検索対象範囲 が短い場合、検索を1回しかしない場合等ではわり と有利。

    余計なメモリを食わない。 イテレータが前方イテレータでOK。 名前が簡単なのでとても良い。(個人の感想です) ※ std::search と同じと書いたけど、実は規格書には何 も書いてない…
  56. 検索アルゴリズム 検索オブジェクトの種類 96 template<class ForwardIterator1, class BinaryPredicate = equal_to<>> class

    default_searcher { public: default_searcher( ForwardIterator1 pat_first, ForwardIterator1 pat_last, BinaryPredicate pred = BinaryPredicate()); template<class ForwardIterator2> pair<ForwardIterator2, ForwardIterator2> operator()(ForwardIterator2 first, ForwardIterator2 last) const; };
  57. 検索アルゴリズム 検索オブジェクトの種類 98 template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,

    class BinaryPredicate = equal_to<>> class boyer_moore_searcher { public: boyer_moore_searcher( RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; };
  58. 検索アルゴリズム 検索オブジェクトの種類 100 template<class RandomAccessIterator1, class Hash = hash<typename iterator_traits<RandomAccessIterator1>::value_type>,

    class BinaryPredicate = equal_to<>> class boyer_moore_horspool_searcher { public: boyer_moore_horspool_searcher( RandomAccessIterator1 pat_first, RandomAccessIterator1 pat_last, Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); template<class RandomAccessIterator2> pair<RandomAccessIterator2, RandomAccessIterator2> operator()(RandomAccessIterator2 first, RandomAccessIterator2 last) const; };
  59. 検索アルゴリズム 107 template<class ForwardIterator, class Searcher> ForwardIterator search(ForwardIterator first, ForwardIterator

    last, const Searcher& searcher); 以下と一緒 return searcher(first, last).first; second 棄てられとる…
  60. コンテナの不完全型サポート 111 N3890 Container<Incomplete Type> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3890.html N4056 Minimal incomplete type

    support for standard containers http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4056.html N4371 Minimal incomplete type support for standard containers, revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4371.html N4390 Minimal incomplete type support for standard containers, revision 3 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4390.html N4510 Minimal incomplete type support for standard containers, revision 4 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4510.html
  61. コンテナの不完全型サポート 導入の背景 115 こんなの出来たらうれしいよね? by 提案ペーパー struct Entry { std::list<Entry>

    messages; // ここではまだ ... // Entry が不完全型 }; 要は、要素型の定義がまだ不完全な状態でもコンテ ナを使いたい。 それ、Boost.Container で出来るよ