SlideShare uma empresa Scribd logo
1 de 38
Baixar para ler offline
constexprとtemplateでコンパイル時にFizzBuzzする
KMC ID:dtyazsk
自己紹介
• KMC ID:dtyazsk
• 所属:理学部1回(数学系志望)
• 普段やってること:プログラミング/DTM/お絵描き
• 趣味:弾幕STG(東方project/怒首領蜂シリーズ)/音ゲー(エニビ/BMS)
• よく使うプログラミング言語:C++
• twitterやってます(@DtYaZsK)
今回やること
• templateとconstexprの概略
• FizzBuzz特化型文字列型を作る
• コンパイル時FizzBuzzを実装する
templateとconstexprってなんぞや
必要事項の確認とか
templateとは
• C++の機能の一つ
• クラスと関数で使える
• クラスまたは数値を引数に取る
• 数値にはコンパイル時整数型定数のみ
• boolは整数型なのでとれる

• 静的に展開しそれぞれクラスを作る
• 例えば右のようなクラスがある
templateとは
• C++の機能の一つ
• クラスと関数で使える
• クラスまたは数値を引数に取る
• 数値にはコンパイル時整数型定数のみ
• boolは整数型なのでとれる

• 静的に展開しそれぞれクラスを作る
• 例えば右のようなクラスがある
• Tmp_class<int,5>でこのように
templateとは
• C++の機能の一つ
• クラスと関数で使える
• クラスまたは数値を引数に取る
• 数値にはコンパイル時整数型定数のみ
• boolは整数型なのでとれる

• 静的に展開しそれぞれクラスを作る
• 例えば右のようなクラスがある
• Tmp_class<double,7>でこのようになる
• 明示的に渡してなくとも
推測できるなら推測してくれる
templateの特殊化
• templateの引数によって処理を変えることも
• template<hoge>でhogeを可変引数部分にし特殊化
• 例えば右のように書く
• 特定されてない部分に
template引数を放り込む
• 完全に特定された状態の特殊化も
templateは必要(template<>と書く)
constexprってなんぞや
• C++11で追加されたキーワード
• コンパイル時に色々するためのキーワードである
• 変数と関数につけて使う
• 最近VC++でも搭載したらしい
• 今回やることはできないようだが

• 読み方がよくわからないが
このスライドでは「コンストエクスプラー」で統一する
• 私がそう読んでるので
• constexprとわかればどう読んでもいいと思う
constexpr定数
• リテラル型(後述)につける
• コンパイル時定数を作る
• template引数に出来たりと嬉しい
• static_assert(今回は省略)もできる
• なお実行時にはconst修飾される
• 定数だから当たり前だろって話
• なおC++11までの話らしい
constexprによる定数式
• コンパイル時と実行時に使える関数
• 引数、返り値はやはりリテラル型
• constexpr定数の初期値に使える
• C++11の段階では関数の実装は
実質return文1つのみ
• 条件演算子と再帰を使って色々できる
• チューリング完全であることが示されている
リテラル型について
• intとかdoubleのような型はリテラル型の元となる
• ポインタ(全て)や参照型(リテラル型のみ)もリテラル型となる
• 以下の条件を満たすクラス(または構造体)はリテラル型となる
• trivialデストラクタを持つ
• ユーザー定義デストラクタを作らなければいい話

• 非staticなメンバの初期化子とコンストラクタ呼び出しが全て定数式
• aggregateであるか
またはコピーでもムーブでもないconstexprコンストラクタが1つ以上
• aggregateとはユーザー定義コンストラクタも非staticメンバに初期化子への初期化子も
基本クラスも仮想関数もなく全てのメンバがpublicな配列またはクラスのこと

• 非staticメンバと基底クラスが全てリテラル型

• constexpr定数にできる
リテラル型の例
• 特に
説明することはない
• 今回は
上のタイプを使う
文字列型(機能限定版)作る
完全版を作る余裕はなかった
注意
• 結構効率の悪い方法でやっております
• 当時私DtYaZsKのC++力がなかったためです
• 今もないだろいいかげんにしろ

• それを考慮に入れて御覧ください
文字列型に必要な物は?
• char型データメンバ
• 文字列結合(operator+)
• 出力関数
• char型やint型から生成するための関数
文字列型に必要な物は?
• char型データメンバ 配列の初期化よくわからなかった(当時)
• 文字列結合(operator+) 使わなくてもFizzBuzzはできる
• 出力関数 定数式にする必要はない
• char型やint型から生成するための関数 定数式である必要がある
配列を使わずに複数の値を保持するには
• template<size_t SIZE>struct contとする
• SIZEは文字数

• コンストラクタにはconst char*型を渡す
• 文字列取得が楽
• 安全性とか知らん

• cont<SIZE-1>型はSIZE-1文字の要素を持つ
• SIZE-1…?
再帰的及び特殊化による定義
• とりあえず右のように定義する
• char型のポインタを引数に渡し
先頭を自分のメンバとして持ち
それ以降の要素をnextに渡す
• cont<1>で特殊化しないと
• 無限ループに陥る
• マトリョーシカを想像すると
わかりやすいか
• 一番外側の人形が先頭の文字を持って次の人形が次の文字を持って…
出力関数を作る
• やはり再帰を用いる
• SIZEは型推論でもとめる
• 1で特殊化する必要性
• そもそもcont<1>に
nextなんてメンバないし
文字列生成関数を作るその1
• 現状ではcont<4> str(“test”)と定義する必要がある
• ユーザーに文字数書かせるのはいかがなものか
• constexpr auto使いたい
• 外部関数として提供されてないとFizzBuzzができない
• もしかしたらできるかもしれないが私には思いつかない
文字列生成関数を作るその1
• 文字数取得はどうするか
• 文字リテラルはconst char[SIZE]型
• 配列の要素数は参照を使えば求めれるらしい
• 例えば右の関数

• そもそも配列の参照型が
右のように定義しないといけない
• それに加え要素数も一致しないといけない
• したがってSIZEの値が確定する→template引数として推測される
文字列生成関数を作るその1
• 文字リテラルだと末端が¥0のためそれは省略する
• すると右のようになる
• 配列の名前だけ書くと
ポインタになるという基本事項を利用
• constexpr autoで書けるようになった
• そもそも今回constexpr auto使わないというのは言ってはいけない
文字列生成関数を作るその2
• 数字からも文字列を作りたい
• to_cont(“FizzBuzz”)はcont<8>型なのでそれで合わせる
• 例えばto_cont(10)でto_cont(“00000010”)と同等にしたい
• 現状ではすぐには思い浮かばない
contのコンストラクタを追加する
• charとcont<SIZE-1>からcont<SIZE>を作れるようにする
• cont<1>はcharのみ

• 赤下線部を追加
• 一体何のためか
補助関数を用いてto_cont(std::size_t)を作る
• 直接代入は出来ない
• 再帰を使う
• N桁目の数字は「10^(N-1)で割った
商を10で割った余り」に等しい
• 右のコードとなる
• ちなみにASCIIで
48は”0”にあたる
そしてコンパイル時FizzBuzzへ
時間が足りてない気がする
コンパイル時FizzBuzzってそもそもなんだ
• コンパイル時にFizzBuzzをする
• 当然(static_assert以外で基本的に)コンパイル時に出力ができない
• 警告を用いた出力は存在するがよくわからない

• 先ほど定義したcontに文字列をコンパイル時に代入する
FizzBuzzのルールと代入関数
• FizzBuzzは数字を順に言っていき
• 3の倍数の時はFizz
• 5の倍数の時はBuzz
• 両方の時はFizzBuzz

に置き換える遊び
• 値を渡しそれによってcont<8>型を返す関数を定義する(上)
配列型を作る
• cont型を作った時と
同様の理屈で
fizzbuzz型を作る
• コンストラクタで
this_resultに今の結果
nextに次の数字を渡す
• FizzBuzzOut()は結果を
一気に表示する
int main()とその他諸々
• もはや言うまでもない
• ちなみにfizzbuzzの定義が
定義なので
result(hoge)でhogeから
FizzBuzzが開始できたり
コンパイル
• 通るか?
コンパイル
• 通った!
結果
• 見えないかも知れません
参考資料その1
• TECHSCORE BLOG
C++で静的配列の要素数を求めるテンプレート関数
• http://www.techscore.com/blog/2013/02/08/how-to-calculate-array-length-in-cand-cpp/

• 本の虫
aggregateと初期化リストの不思議
• http://cpplover.blogspot.jp/2010/09/aggregate.html

• ボレロ村上 – EniyGmaA Code
リテラル型クラスの条件、および「中3女子でもわかる constexpr」の訂正
• http://d.hatena.ne.jp/boleros/20130718/1374155184
参考資料その2
• 中3女子でもわかる constexpr
• http://www.slideshare.net/GenyaMurakami/constexpr-10458089

• 中3女子が狂える本当に気持ちのいい constexpr
• http://www.slideshare.net/GenyaMurakami/constexpr-11509325

• Constexpr 中3女子テクニック ー実践と濫用そしてC++14へ
• http://www.slideshare.net/GenyaMurakami/constexpr-23355469
今回の反省点と勉強点
• String型の実装が垣間見た気がする
• 完全ではないにしろconstexpr力が高まった

• cont型の実装が妥協だらけだった
• FizzBuzz特化型でした
• 効率とか何も考えてません
• operator==ぐらい実装すべきだったか
• あればコンパイル時にFizzBuzzできていることが確認できる(by static_assert)

• constexprライブラリすごいなぁと
• 高校の後輩が出力までコンパイル時に終わらせてて言葉が出ない
• templateと警告使ってる
ご清聴ありがとうございました
今回のコードは
http://melpon.org/wandbox/permlink/sxZm8aNobZwX5baR

で公開してます

Mais conteúdo relacionado

Mais procurados

組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
Genya Murakami
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
yohhoy
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
Satoshi Sato
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
alwei
 

Mais procurados (20)

組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだconstexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
直交領域探索
直交領域探索直交領域探索
直交領域探索
 
CRC-32
CRC-32CRC-32
CRC-32
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
ネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分けネットワーク ゲームにおけるTCPとUDPの使い分け
ネットワーク ゲームにおけるTCPとUDPの使い分け
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
カスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについてカスタムメモリマネージャと高速なメモリアロケータについて
カスタムメモリマネージャと高速なメモリアロケータについて
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
Pythonによる黒魔術入門
Pythonによる黒魔術入門Pythonによる黒魔術入門
Pythonによる黒魔術入門
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理.NET Core 3.0時代のメモリ管理
.NET Core 3.0時代のメモリ管理
 
ドロネー三角形分割
ドロネー三角形分割ドロネー三角形分割
ドロネー三角形分割
 

Mais de 京大 マイコンクラブ

Mais de 京大 マイコンクラブ (20)

テキストファイルを読む💪 第1回
テキストファイルを読む💪  第1回テキストファイルを読む💪  第1回
テキストファイルを読む💪 第1回
 
かわいくなろうとしたら語彙力が下がった話
かわいくなろうとしたら語彙力が下がった話かわいくなろうとしたら語彙力が下がった話
かわいくなろうとしたら語彙力が下がった話
 
Common Lisp入門
Common Lisp入門Common Lisp入門
Common Lisp入門
 
多倍長整数の乗算と高速フーリエ変換
多倍長整数の乗算と高速フーリエ変換多倍長整数の乗算と高速フーリエ変換
多倍長整数の乗算と高速フーリエ変換
 
つくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタつくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタ
 
Geometry with Unity
Geometry with UnityGeometry with Unity
Geometry with Unity
 
セミコロンレスc++
セミコロンレスc++セミコロンレスc++
セミコロンレスc++
 
エンジニアと健康
エンジニアと健康エンジニアと健康
エンジニアと健康
 
女の子になれなかった人のために
女の子になれなかった人のために女の子になれなかった人のために
女の子になれなかった人のために
 
Pietで競プロしよう
Pietで競プロしようPietで競プロしよう
Pietで競プロしよう
 
もし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったらもし太陽のコアがIntelCoreだったら
もし太陽のコアがIntelCoreだったら
 
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
C# ゲームプログラミングはホントにメモリのことに無頓着でいいの?
 
プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜プログラムを高速化する話Ⅱ 〜GPGPU編〜
プログラムを高速化する話Ⅱ 〜GPGPU編〜
 
ドット絵でプログラミング!難解言語『Piet』勉強会
ドット絵でプログラミング!難解言語『Piet』勉強会ドット絵でプログラミング!難解言語『Piet』勉強会
ドット絵でプログラミング!難解言語『Piet』勉強会
 
No SSH (@nojima; KMC関東例会)
No SSH (@nojima; KMC関東例会)No SSH (@nojima; KMC関東例会)
No SSH (@nojima; KMC関東例会)
 
DTM練習会2017第1.5回 「伴奏の付け方」
DTM練習会2017第1.5回 「伴奏の付け方」DTM練習会2017第1.5回 「伴奏の付け方」
DTM練習会2017第1.5回 「伴奏の付け方」
 
hideya流 テストプレイ観察術
hideya流 テストプレイ観察術hideya流 テストプレイ観察術
hideya流 テストプレイ観察術
 
暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編暗号技術入門 秘密の国のアリス 総集編
暗号技術入門 秘密の国のアリス 総集編
 
Altseed
AltseedAltseed
Altseed
 
C#でゲームを作る2016 第8回
C#でゲームを作る2016 第8回C#でゲームを作る2016 第8回
C#でゲームを作る2016 第8回
 

Constexprとtemplateでコンパイル時にfizz buzz