SlideShare une entreprise Scribd logo
1  sur  24
ナウなヤングに
バカうけの
イカした
タグ付き共用体
自己紹介
でちまる
http://libdechimal.so
https://twitter.com/decimalbloat
パワポで生産性が3倍,更に最新バージョンの2016だからUXが5倍,すなわ
ち100倍の資料作成力だ.
タグ付き共用体とは
struct u {
int which;
union {
hoge x;
fuga y;
piyo z;
};
};
共用体に今入ってる値の種類を表わすフラグを付けたもの
今回はこれをめっちゃモダナイズした
リポジトリ
https://github.com/dechimal/TaggedUnion
コード例のprefix
using namespace desalt::tagged_union;
template<typename ...Ts>
using u = tagged_union<Ts...>;
基本的な機能
基本
u<int, double> x{_0, 42};
x.which(); // 0
x.get(_0); // 42
x.get(_1); // error
x = {_1, 123.0};
x.which() // 1
x.get(_1) // 123.0;
x.get(_0) // error
// あとコピーとかムーブとか
同じ型どうしでも合併できる
u<int, int> x{_0, 42};
x.get(_0); // 42
x = {_1, 142};
y.get(_1); // 142
ディスパッチ
u<hoge, fuga> x{_0, hoge{}};
auto s = x.dispatch([] (tag<0>) {
return “hoge";
}, [] (tag<1>) {
return “fuga";
});
std::cout << s << std::endl; // hoge
再帰
using tree = u<int, std::tuple<int, _, _>>;
int sum(tree const & t) {
t.when([] (tag<0> n, int n) {
return n;
}, [] (tag<1>, std::tuple<tree, tree> const & t) {
return ::sum(std::get<0>(t)) + ::sum(std::get<1>(t));
});
}
tree t{_1, std::make_tuple(1, tree{_0, 2}, tree{_0, 3})};
std::cout << sum(t) << std::endl; // 6
コピー
u<int> x{_1, 42}, y = x;
y = {_1, 0};
std::cout << x.get(_0) << std::endl; // 42
std::cout << y.get(_1) << std::endl; // 0
deep copyする.
変換
struct hoge {};
struct fuga : hoge {};
u<int, fuga> x{_1, {}};
u<long, hoge> y = x;
要素の数が同じで,対応する位置の要素が全て変換可能なときに変換可能.
色々な型
非負整数 (こう度な政治的判
断に基づく表現)
struct unit {};
using nat = u<unit, _>;
int to_int(nat const & n) {
return n.when([] (tag<0>, unit) {
return 0;
}, [] (tag<1>, nat const & m) {
return ::to_int(m) + 1;
});
}
nat two{_1, nat{_1, nat{_1}}};
std::cout << ::to_int(two) << std::endl; // 2
リスト
template<typename T>
using list = u<unit, std::tuple<T, _>>;
template<typename T, typename Z, typename F>
auto foldr(list<T> const & l, Z z, F f) {
return n.when([] (tag<0>, unit) {
return z;
}, [] (tag<1>, std::tuple<T, list<T>> const & m) {
return f(std::get<0>(m), ::foldr(std::get<1>(m), z, f));
});
}
JSON
using json_value = u<
nullptr,
bool,
double,
std::string,
std::vector<_>,
std::unordered_map<std::string, _>
>;
using json = u<
std::vector<json_value>,
std::unordered_map<std::string, json_value>
>;
Bottom
using botom = u<_>;
この型の有効な値は得られない.
しかし,(コピー/ムーブ)(構築/代入)および破棄はできる.
bottom型を戻り値とする関数の呼びだしは,return以外の方法でしか戻って
こないか,決して制御が戻らないことを表現するのに使える(実際に使って便
利とは言っていない).
[[noreturn]]との違いは,例えばu<hoge, bottom>などという型で,部分的に
制御が戻ってこない場合があることを型上で表現できる(実際に表現して便
利とは言っていない).
高度な機能
不動点コンビネータ
さっきnatの値をintの値に変換するために int to_int(nat) という関数を書いた
が,あれはこう書ける.
n.when(::fix(::tie([] (auto, tag<0>, unit) {
return 0;
}, [] (auto f, tag<1>, nat const & m) -> int {
return f(m);
})));
不動点コンビネータ
n.when(
::fix( ::tie(
[] (auto, tag<0>, unit) { return 0; },
[] (auto f, tag<1>, nat const & m) -> int { return f(m); })));
tieはBoostのmake_overloaded_functionみたいなもので,複数の関数を一つ
にまとめた関数オブジェクト.
実際に呼び出されるのは,tieに与えた順に探索して最初に呼び出せるもの
(だったと思う).
fixは不動点コンビネータで,与えられた関数を再帰呼び出しする.これはラム
ダ式で再帰するために使う.上例の各ラムダ式の最初の引数が,::fix(…)と
同じ関数である.
static if
template<typename T>
auto has_hoge() {
return ::static_if([] (auto, std::enable_if<(sizeof(T) > 12)>::type* = nullptr) {
return std::true_type{};
}, [] (auto) {
return std::false_type{};
});
}
Tのサイズが12以上ならtrue_type,そうでなければfalse_typeの値を返す関
数.
分岐はSFINAEでやっているので異なる型を返せる.
static if
::static_if([] (auto dep, typename decltype(dep(T{}))::hoge * = {}) {
…
}, [] (auto) {
…
});
Tがhogeという名前でメンバ型があるかどうかで分岐する.
最初の引数はdependent type/expressionを作るためのもので,static ifの中
で渡される.これをなくして単に
[] (typename T::hoge * = {}) {}
とするとSFINAEしないで::hogeがないというコンパイルエラーを引き起こす.
相互再帰
using u0 = u<hoge, _, _r1>;
using u1 = u<fuga, _, u0>;
u1 x = …;
これは,
◦ decltype(x.get(_0)) == fuga;
◦ decltype(x.get(_1)) == u1;
◦ decltype(x.get(_2).get(_0)) == hoge
◦ decltype(x.get(_2).get(_1)) == u0;
◦ decltype(x.get(_2).get(_2)) == u1;
となる.
代入の例外安全性
コードごらんなさい.
https://github.com/dechimal/TaggedUnion/blob/7bbb376304913eaecf6e8e0
168e215a62c0dede3/tagged_union.hpp#L312

Contenu connexe

Tendances

C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプKohsuke Yuasa
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜勝成 鈴江
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門natrium11321
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Takashi Hoshino
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときShintarou Okada
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLispKent Ohashi
 
C++入門?
C++入門?C++入門?
C++入門?tsudaa
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~Nobuhisa Koizumi
 
C++ lecture-2
C++ lecture-2C++ lecture-2
C++ lecture-2sunaemon
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編egtra
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らないdigitalghost
 

Tendances (20)

More C++11
More C++11More C++11
More C++11
 
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプC++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
 
C++11
C++11C++11
C++11
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
Sml#探検隊
Sml#探検隊Sml#探検隊
Sml#探検隊
 
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
 
Functional Way
Functional WayFunctional Way
Functional Way
 
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるときunique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
Nginx lua
Nginx luaNginx lua
Nginx lua
 
Objc lambda
Objc lambdaObjc lambda
Objc lambda
 
C++入門?
C++入門?C++入門?
C++入門?
 
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
 
C++ lecture-2
C++ lecture-2C++ lecture-2
C++ lecture-2
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
 

Similaire à ナウなヤングにバカうけのイカしたタグ付き共用体

TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューAkira Inoue
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swiftnecocen
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
すごいHaskell楽しく学ぼう-第12章モノイド-
すごいHaskell楽しく学ぼう-第12章モノイド-すごいHaskell楽しく学ぼう-第12章モノイド-
すごいHaskell楽しく学ぼう-第12章モノイド-Hiromasa Ohashi
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイドShinta Hatatani
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)Shoji Haraguchi
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式digitalghost
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Takuya Tsuchida
 
[第2版]Python機械学習プログラミング 第14章
[第2版]Python機械学習プログラミング 第14章[第2版]Python機械学習プログラミング 第14章
[第2版]Python機械学習プログラミング 第14章Haruki Eguchi
 

Similaire à ナウなヤングにバカうけのイカしたタグ付き共用体 (20)

TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
MP in Scala
MP in ScalaMP in Scala
MP in Scala
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
CLR/H No.35-2
CLR/H No.35-2CLR/H No.35-2
CLR/H No.35-2
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
すごいHaskell楽しく学ぼう-第12章モノイド-
すごいHaskell楽しく学ぼう-第12章モノイド-すごいHaskell楽しく学ぼう-第12章モノイド-
すごいHaskell楽しく学ぼう-第12章モノイド-
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
boost tour 1.48.0 all
boost tour 1.48.0 allboost tour 1.48.0 all
boost tour 1.48.0 all
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイド
 
初めてのSTL
初めてのSTL初めてのSTL
初めてのSTL
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
 
What is template
What is templateWhat is template
What is template
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
 
[第2版]Python機械学習プログラミング 第14章
[第2版]Python機械学習プログラミング 第14章[第2版]Python機械学習プログラミング 第14章
[第2版]Python機械学習プログラミング 第14章
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 

Plus de digitalghost

拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作ったdigitalghost
 
Define and expansion of cpp macro
Define and expansion of cpp macroDefine and expansion of cpp macro
Define and expansion of cpp macrodigitalghost
 
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロdigitalghost
 
Boost.Preprocessorでプログラミングしましょう
Boost.PreprocessorでプログラミングしましょうBoost.Preprocessorでプログラミングしましょう
Boost.Preprocessorでプログラミングしましょうdigitalghost
 
Preprocess-time Lambda Expression
Preprocess-time Lambda ExpressionPreprocess-time Lambda Expression
Preprocess-time Lambda Expressiondigitalghost
 

Plus de digitalghost (6)

拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
拡張可能でprintfっぽい書式指定ができて書式指定文字列と引数をコンパイル時に検証できる文字列フォーマット関数を作った
 
Define and expansion of cpp macro
Define and expansion of cpp macroDefine and expansion of cpp macro
Define and expansion of cpp macro
 
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
二分探索法で作る再帰呼び出しできるCプリプロセッサマクロ
 
No skk, no life.
No skk, no life.No skk, no life.
No skk, no life.
 
Boost.Preprocessorでプログラミングしましょう
Boost.PreprocessorでプログラミングしましょうBoost.Preprocessorでプログラミングしましょう
Boost.Preprocessorでプログラミングしましょう
 
Preprocess-time Lambda Expression
Preprocess-time Lambda ExpressionPreprocess-time Lambda Expression
Preprocess-time Lambda Expression
 

ナウなヤングにバカうけのイカしたタグ付き共用体