$30 off During Our Annual Pro Sale. View Details »

明日から使える fold expression テクニック

明日から使える fold expression テクニック

歌舞伎座.tech 番外編「江添亮の詳説C++17」出版記念で発表したLTの資料

白山風露

March 14, 2018
Tweet

Transcript

  1. 明日から使える fold expression テクニック

  2. 明日から使えるの? • GCC => 6 • Clang => 3.6 •

    MSVC => 19.12 (Visual Studio 15.5) http://en.cppreference.com/w/cpp/compiler_support 調べ →明日から使える!
  3. Fold expressionとは?

  4. Fold expressionとは? • C++17で追加された新機能 • パラメーターパックを演算子で結合して展開できる • 別の関数を用意しなくても良くなる

  5. Fold expression の文法 Unary fold expression と Binary fold expression

    がある
  6. Fold expression の文法 Unary fold expression “exp” がパラメーターパックを含む式、 ”@” を何らかの二項演算子として、

    (exp @ ...) // (1) (... @ exp) // (2)
  7. Fold expression の文法 Unary fold expression 長さnのパラメーターパックのk番目の項を含む式をexp k として、 exp

    1 @ (exp 2 @ (... @ (exp n-2 @ exp n-1 ))) // (1) (((exp 1 @ exp 2 ) @ ...) @ exp n-2 ) @ exp n-1 // (2) と展開される。
  8. Fold expression の文法 Unary fold expression パラメーターパックが空のとき、以下の演算子に関してはデフォルトの値が存在する。 • && →

    true • || → false • , → void() それ以外の演算子の場合、パラメーターパックが空だとエラーになる。
  9. Fold expression の文法 Binary fold expression “exp” がパラメーターパックを含む式、 ”init” を任意の式、”@”

    を何らかの二項演算子として、 (exp @ ... @ init) // (1) (init @ ... @ exp) // (2)
  10. Fold expression の文法 Binary fold expression 長さnのパラメーターパックのk番目の項を含む式をexp k として、 exp

    1 @ (exp 2 @ (... @ (exp n-2 @ (exp n-1 @ init)))) // (1) ((((init @ exp 1 ) @ exp 2 ) @ ...) @ exp n-2 ) @ exp n-1 // (2) と展開される。
  11. Fold expression の文法 これは fold expression ではない func(exp...); return {

    exp... };
  12. 1.複数の真偽値の論理和や論理積を取る template<bool ...args> inline constexpr auto conjunction = (args &&

    ...); template<bool ...args> inline constexpr auto disjunction = (args || ...);
  13. 1.複数の真偽値の論理和や論理積を取る constexpr auto conjunction = [](std::initializer_list<bool> init) { bool result

    = true; for (bool v : init) { result &= v; if (!v) return false; } return result; };
  14. 2.一致する型を数える template<typename T, typename ...Args> inline constexpr auto type_count =

    (std::size_t{} + ... + std::is_same_v<T, Args>);
  15. template<typename T, typename ...Args> inline constexpr auto type_index_of = []{

    std::size_t i = 0; ((!std::is_same_v<T, Args> && ++i) && ...); return i; }(); 3.先頭から一致する型の位置を探す
  16. template<typename T, std::size_t index, typename ...Args> inline constexpr auto type_index_of

    = []{ std::size_t i = 0; (((i < index || !std::is_same_v<T, Args>) && ++i) && ...); return i; }(); 4.途中から一致する型の位置を探す
  17. inline constexpr auto call = [](auto&& func, auto&& ...args) {

    (void(func(std::forward<decltype(args)>(args))), ...); }; 5.全ての値に関して関数を呼び出す
  18. 君も明日からfold expressionを使おう!

  19. 自己紹介 名前:吉田大樹 仕事:プログラマー。電子書籍リーダーの開発。最近は業務では C++よりもTypeScriptやってる twitter: @kazatsuyu