Home
Explore
Submit Search
Upload
Login
Signup
Advertisement
Check these out next
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
競技プログラミングのためのC++入門
natrium11321
クロージャデザインパターン
Moriharu Ohzu
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake
Real World OCamlを読んでLispと協調してみた
blackenedgold
最新C++事情 C++14-C++20 (2018年10月)
Akihiko Matuura
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
勝成 鈴江
1
of
60
Top clipped slide
Pfi Seminar 2010 1 7
Jan. 7, 2010
•
0 likes
6 likes
×
Be the first to like this
Show More
•
3,418 views
views
×
Total views
0
On Slideshare
0
From embeds
0
Number of embeds
0
Download Now
Download to read offline
Report
Preferred Networks
Follow
Vice-President at Preferred Networks
Advertisement
Advertisement
Advertisement
Recommended
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka
12.3K views
•
66 slides
Map
kikairoya
9.9K views
•
41 slides
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
9.3K views
•
59 slides
ゲーム開発者のための C++11/C++14
Ryo Suzuki
102.3K views
•
157 slides
不遇の標準ライブラリ - valarray
Ryosuke839
7.3K views
•
36 slides
C++11概要 ライブラリ編
egtra
3K views
•
46 slides
More Related Content
Slideshows for you
(20)
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
•
10.9K views
競技プログラミングのためのC++入門
natrium11321
•
32.9K views
クロージャデザインパターン
Moriharu Ohzu
•
19.5K views
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
•
30K views
BoostAsioで可読性を求めるのは間違っているだろうか
Yuki Miyatake
•
14.1K views
Real World OCamlを読んでLispと協調してみた
blackenedgold
•
4K views
最新C++事情 C++14-C++20 (2018年10月)
Akihiko Matuura
•
1.7K views
C++でのゲームプログラミングをしたときのお話 札幌C++勉強会 #4 〜スタートゲームプログラミング〜
勝成 鈴江
•
5.2K views
Emcjp item21
MITSUNARI Shigeo
•
2.3K views
関数型プログラミング入門 with OCaml
Haruka Oikawa
•
12.3K views
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
•
3.5K views
Unity2015_No10_~UGUI&Audio~
CHY72
•
1.1K views
Emcpp item31
mitsutaka_takeda
•
10.3K views
今から始める Lens/Prism
Naoki Aoyama
•
7.9K views
(define)なしで再帰関数を定義する
blackenedgold
•
2.4K views
これからの「言語」の話をしよう ―― 未来を生きるためのツール
Nobuhisa Koizumi
•
1.3K views
Visual C++で使えるC++11
nekko1119
•
36.8K views
闇魔術を触ってみた
Satoshi Sato
•
6.6K views
C++入門?
tsudaa
•
3.6K views
Van laarhoven lens
Naoki Aoyama
•
1.9K views
Viewers also liked
(8)
手書きスライド
Hideyuki Tanaka
•
4.2K views
C++でHello worldを書いてみた
firewood
•
6.8K views
Icfp2009
Hideyuki Tanaka
•
1.2K views
Xpath in-lens
Hideyuki Tanaka
•
5.7K views
Monad tutorial
Hideyuki Tanaka
•
13.3K views
IdrisでWebアプリを書く
Hideyuki Tanaka
•
19.4K views
関数プログラミング入門
Hideyuki Tanaka
•
21.7K views
できる!並列・並行プログラミング
Preferred Networks
•
26.4K views
Advertisement
Similar to Pfi Seminar 2010 1 7
(20)
Continuation with Boost.Context
Akira Takahashi
•
2.1K views
TypeScript 1.0 オーバービュー
Akira Inoue
•
16.5K views
知って得するC#
Shota Baba
•
9.7K views
Flutterを体験してみませんか
cch-robo
•
254 views
Python standard 2022 Spring
anyakichi
•
200 views
SystemC Tutorial
kocha2012
•
9K views
Boost.Flyweight
gintenlabo
•
2.7K views
わんくま同盟大阪勉強会#61
TATSUYA HAYAMIZU
•
952 views
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
•
5.2K views
今日からできる!簡単 .NET 高速化 Tips
Takaaki Suzuki
•
34.1K views
ぱっと見でわかるC++11
えぴ 福田
•
1.6K views
asm.js x emscripten: The foundation of the next level Web games
Noritada Shimizu
•
2K views
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
y_taka_23
•
21.2K views
Javaセキュアコーディングセミナー東京第3回講義
JPCERT Coordination Center
•
1.8K views
規格書で読むC++11のスレッド
Kohsuke Yuasa
•
17.5K views
C++0x総復習
道化師 堂華
•
4.9K views
C++0x 言語の未来を語る
Akira Takahashi
•
1.7K views
.NET Core 2.x 時代の C#
信之 岩永
•
6.2K views
Live Coding で学ぶ C# 7
Takaaki Suzuki
•
862 views
20120422i phonedeveloperworkshoppublished
Yoichiro Sakurai
•
761 views
More from Preferred Networks
(20)
Optunaを使ったHuman-in-the-loop最適化の紹介 - 2023/04/27 W&B 東京ミートアップ #3
Preferred Networks
•
565 views
深層学習の新しい応用と、 それを支える計算機の進化 - Preferred Networks CEO 西川徹 (SEMICON Japan 2022 Ke...
Preferred Networks
•
198 views
Kubernetes ControllerをScale-Outさせる方法 / Kubernetes Meetup Tokyo #55
Preferred Networks
•
20.3K views
Kaggle Happywhaleコンペ優勝解法でのOptuna使用事例 - 2022/12/10 Optuna Meetup #2
Preferred Networks
•
1.1K views
最新リリース:Optuna V3の全て - 2022/12/10 Optuna Meetup #2
Preferred Networks
•
1.9K views
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Preferred Networks
•
1.6K views
スタートアップが提案する2030年の材料開発 - 2022/11/11 QPARC講演
Preferred Networks
•
218 views
Deep Learningのための専用プロセッサ「MN-Core」の開発と活用(2022/10/19東大大学院「 融合情報学特別講義Ⅲ」)
Preferred Networks
•
424 views
PFNにおける研究開発(2022/10/19 東大大学院「融合情報学特別講義Ⅲ」)
Preferred Networks
•
400 views
自然言語処理を 役立てるのはなぜ難しいのか(2022/10/25東大大学院「自然言語処理応用」)
Preferred Networks
•
129 views
Kubernetes にこれから入るかもしれない注目機能!(2022年11月版) / TechFeed Experts Night #7 〜 コンテナ技術を語る
Preferred Networks
•
129 views
Matlantis™のニューラルネットワークポテンシャルPFPの適用範囲拡張
Preferred Networks
•
568 views
続・PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜 #2
Preferred Networks
•
1.4K views
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Preferred Networks
•
1.5K views
KubeCon + CloudNativeCon Europe 2022 Recap / Kubernetes Meetup Tokyo #51 / #k...
Preferred Networks
•
1.4K views
KubeCon + CloudNativeCon Europe 2022 Recap - Batch/HPCの潮流とScheduler拡張事例 / Kub...
Preferred Networks
•
1.2K views
Topology Managerについて / Kubernetes Meetup Tokyo 50
Preferred Networks
•
715 views
PFN Summer Internship 2021 / Kohei Shinohara: Charge Transfer Modeling in Neu...
Preferred Networks
•
3.2K views
PFN のオンプレML基盤の取り組み / オンプレML基盤 on Kubernetes 〜PFN、ヤフー〜
Preferred Networks
•
2.7K views
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
Preferred Networks
•
1.5K views
Advertisement
Pfi Seminar 2010 1 7
Caution!
本発表には次のものは含まれません C++の有用なプログラミング技法 広くつかわれるべきテクニック その他なにか視聴者に役立つもの そういうのを期待された方はあしからず
自己紹介 田中英行 (@tanakh,
id:tanakh) Haskell愛好家 C++歴 1998年 ~ 2005年ぐらいまでは漫然と使っていました 社内用C++ライブラリ(pficommon)を作成 C++のきもさを再認識 その辺で得られた知見を話します ○ ※実際に使われているわけではないです
pficommon Boostの広く利用できる部分(tr1) データ構造いろいろ
サーバー書く向け機能 マルチスレッド 各種プロトコル RPC ウェブアプリ向け機能 DSL
本日の内容 ユーザー定義構文 Serializable万能説
Stream Fusion の三本立て
概要
C++の構文のように扱える構文を 定義してみようとすると、 それがどういう意味を持つのだろうか、 というお話
ユーザー定義構文 ユーザー定義する組み込み構文のように
扱えるもの 例えば synchronized (Java) using (C#) actor (Scala) のようなものがC++でも書けると嬉しい ですね
ほかの言語の例
Lisp マクロ・高階関数 Haskell 高階関数・モナドを引数にとる関数 Ruby ブロックをとる関数 Scala 最後の引数にラムダ式をとる関数を書くと それっぽく見える
例:foreach (for-each (lambda (x)
forM_ [1..5] $ ¥x -> (display x) print x ‘(1 2 3 4 5)) (1..5).each{|x| List(1,2,3,4,5).foreach{ x => p x println(x) } }
C++でのユーザー定義構文(1)
statementを引数に取るマクロを書き、 組み込みの構文要素に置換する #define foreach(v, c, s) ¥ for(typeof(c.begin()) it=c.begin(); it!=c.end(); it++){ ¥ v = *it; ¥ s ¥ } … vector<int> v; v.push_back(1); … foreach(int x, v, { cout<<x<<endl; })
問題点
簡単に書けて、扱いやすいが、 かっこ悪い foreach(, , {}) ↑ 括弧の中に{}があるのが耐えられない }) って… foreach(int x, v) { cout<<x<<endl; } のように書きたい
C++でのユーザー定義構文(2)
statementが後ろに来て整合性が取れる ようなマクロを書く #define foreach(v, c) ¥ for (bool b=true; b; ) ¥ for (v; b; b=false) ¥ for(typeof(c.begin()) it=c.begin(); it!=c.end() && (v=*it, true); it++) … vector<int> v; v.push_back(1); … foreach(int x, v){ cout<<x<<endl; }
C++でのユーザー定義構文(2) この書き方は美しいが、
記述力を制限される 既存の制御構文の後ろに文を置けるだけ
後処理
synchronized(v){ … } のようなことを実 現するには、{ … } の後に処理をさせな ければならない
forを使う方法 後続の文より後に処理をさせる方法 forを使う
#define synchronized(v) ¥ for (bool b=true; ¥ b && (v.lock(), true); ¥ b=false, v.unlock()) #define synchronized(v) ¥ for (bool b=true; b; ) ¥ for (scoped_lock lk(v); b; b=false) break, continueが食われてしまう
ifを使う方法
ifの中で変数を宣言すれば、 後続の文の後にデストラクタを動かせる #define synchronized(v) ¥ if (scoped_lock lk=scoped_lock(v))
ifを使う方法(2) コピー可能なクラスを定義する trueを返すoperator
bool() を定義する デストラクタを定義する class hoge { … }; if (hoge h=hoge()) stat; 処理の流れ hoge::hoge() hoge::operator bool() stat hoge::~hoge()
改良
operator bool() はfalseを返したほうがいい #define synchronized(v) ¥ if (scoped_lock lk=scoped_lock(v)); ¥ else
活用例:CGI DSL class
my_cgi : public cgi{ public: void run(){ html__{ head__{ title__{ text__("タイトル"); } } body__{ a__{ href__ = "http://kzk9.net/blog/"; text__("super blog!"); } br__; } } } };
議論 hoge(…){ …
} の形で、 前処理→処理→後処理 の形のユーザー 定義構文が書けることが分かった だがそれだけだろうか? こういうことができるということは、 つまりどういうことなのだろうか
見えざる継続
継続とは ある計算過程のある瞬間における、その過 程の未来全体を表すもの、あるいは計算過 程の実行スナップショットと説明される。 (Wikipedia) Schemeなどでは言語レベルでサポート 継続は、実行中のどんな計算機プログラ ムにも存在する
関数呼び出しと継続 関数呼び出しとはすなわち、継続をとも
なう手続きへのジャンプ 関数が呼ばれた= 関数から返った後の継続が手に入る int foo(){ return 1; } foo()が呼ばれる際に渡される継続 ・返された値に2を書けて void bar() ・それを表示する { cout<<foo()*2<<endl; 実際のところC++では、 } ・スタック ・リターンアドレス の対として表現される
ユーザー定義構文では
hoge::operator bool() が呼ばれた瞬間の 継続に注目する class hoge { … }; if (hoge h=hoge()) stat; 処理の流れ hoge::hoge() hoge::operator bool() ← trueを返せば stat → hoge::~hoge() → … stat falseを返せば hoge::~hoge() → … hoge::~hoge() なる継続
継続を取り出す
callee save レジスタ、スタック、リター ンアドレスを取り出す cont get_ret_cont(){ regs=get_callee_save_regs(); stack=get_stack(); ret=get_ret_addr(); return (regs, stack, ret); }
継続が取り出せるなら
operator bool()にて、継続を取り出し、 さらに文実行後の継続を設定し、stat後 の処理の流れを決められる hoge::operator bool() { cont c=get_ret_cont(); next=…; c(true); } hoge::~hoge() { next(); }
文を後ろに置く=継続を渡す つまるところ、if (hoge
h=hoge()) { … } は 後ろの文を引数に関数を呼び出しているの と同じである Schemeの高階関数や、Rubyのブロック構 文と同じことができる
例:スレッド
thread{ … } でスレッドを立てる 後続の文が終了するとスレッド終了 mutex m; int n; int main() { thread{ for (int i=0; i<10; i++) synchronized(m) n++; } for (int i=0; i<10; i++) synchronized(m) n--; }
実装 class thread_forker{ …
}; thread_forker::operator bool(){ cont c=get_ret_cont(); pthread_create(&tid, NULL, bind(apply_cont, c, true)); c(false); } thread_forker::~thread_forker(){ pthread_exit(NULL); }
別スレッドでの継続の起動 スタックを別のスタックにコピーする ポインタの張り替えなどめんどい
ret ret ret frame frame frame ret ret ret frame frame frame
まとめ C++でユーザー定義構文は意外ときれい
に作れるんじゃなかろうか ポータブルな実装ができるかどうか
概要 シリアライザというものがあります シリアライザが意外と色々なところに使
えるという話
シリアライザとは データをバイト列に変換したり(シリアラ
イズ)、バイト列からデータに変換したり (デシリアライズ)するもの クラスやコンテナの内容をファイルに保存 したり、ネットワーク越しに転送したりす るのにとても便利
boost::serialization
Boostに入っているシリアライズライブ ラリ class hoge{ private: string a; vector<int> b; friend class boost::serialization::access; template <class Archive> void serialize(Archive &ar){ ar & a & b; } };
boost::serializationの特徴 シリアライズとデシリアライズを
共通のコードで記述 テンプレートでディスパッチ hoge h; text_oarchive oa(cout); oa << h; // text_oarchiveを引数にserializeが呼ばれる hoge g; text_iarchive ia(cin); ia >> h; // text_iarchiveを引数にserializeが呼ばれる
仕組み
serialize()関数をオーバーロード template <class Archive> Archive &operator &(Archive &ar, T &v){ serialize(ar, v); return ar; } void serialize(text_iarchive &ar, int n){ ar.read_int(n); } void serialize(text_oarchive &ar, int n){ ar.write_int(n); }
シリアライズするというのはどうい うことか?
クラスのシリアライズ メンバの列挙 コンテナのシリアライズ データの列挙
テンプレートでのシリアライズ serializeがテンプレートメンバ関数 シリアライズ・デシリアライズを
共通化 色々なシリアライザ(text, binary)に適用 可能 拡張可能 → シリアライザじゃなくてもいいので は?
型を書きだす
データの代わりに、型を書きだしてみる class type_oarchive{ … }; template <class T> void serialize(type_oarchive &oa, T &v){ // デフォルト oa.enter_struct(); serialize(oa, v); oa.leave_struct(); } void serialize(type_oarchive &oa, int &n){ // 特殊化 oa.add(new int_type(true, sizeof(int))); } …
型を書きだす(2)
コンテナ型は特殊化する template <class T> void serialize(type_oarchive &oa, vector<T> &v){ oa.add(new array_type(get_type<T>()); } template <class K, class V> void serialize(type_oarchive &oa, map<K, V> &v){ oa.add(new map_type(get_type<K>(), get_type<V>()); }
型を書きだす(3)
型情報取得関数 template <class T> type_info *get_type() { T v; type_oarchive oa; oa << v; return oa.get(); }
Serializable = Reflectable
値の代わりに型を書きだすことにより、 Serializableなクラスは(部分的には) Reflectableなクラスとなる Reflectableなクラスは明らかに Serializableに出来るのでこれはそう おかしな話ではない つまり、(部分的には)Serializableと Reflectableは等価である
応用例:RPC // シグニチャ RPC_PROC(add, int(int,
int)) // メソッド定義 RPC_GEN(calc, add) // クラス定義 // サーバ // クライアント int add(int x, int y){ return x+y; } hoge_client cli(“localhost”, 12345); int main(){ cout<<cli.call_add(1,2)<<endl; hoge_server serv; // ↑ 3が返ってくるはず serv.set_add(&add); serv.serv(12345, 10); }
RPC説明 適当に関数のシグニチャを定義して、
それに合う関数をセットする 関数の引数、返り値はソケットでやり取 りされる → シリアライズ可能でなけれ ばならない
RPC:クライアントコード生成
言語bindingを自動で生成 C++ソースを読み込む パーズするのは大変すぎる g++にやらせる リフレクションする RPCの型情報が取れる 好きなコード生成できる RPCでやり取りするデータはすべてSerializable でなければならないはずなので、すべて何もし なくてもリフレクション出来るはずである for
RPC:テスト生成
おなじ原理でRPCテスト用のWebサー バーをC++コードから自動で生成
まとめ
Serializableなデータ構造は思ったより 有用だ
概要
ストリームを扱う計算が テンプレートで速くなるという話
ストリーム
(ここでは)何かデータの列 配列とか 外部メモリ上のデータとか ストリームに対する演算 map filter fold sort merge など…
例
ストリームに対する演算の繰り返し vector<int> v, w, x; for (int i=0; i<100; i++) v.push_back(i); remove_copy_if(v.begin(), v.end(), back_inserter(w), is_even()); transform(w.begin(), w.end(), back_inserter(x), div2()); 中間配列ができる 配列を二回なめる 外部メモリを扱う時に特に顕著 for
1パスでやるには
一か所に書けばいい vector<int> v, x; for (int i=0; i<100; i++) v.push_back(i); for (int i=0; i<v.size(); i++) if (v[i]%2==0) x.push_back(v[i]/2); モジュラリティが低い さっきのように書いて、こうなってほしい
遅延ストリーム
それぞれの処理で一気に配列を舐めるのが いけない → 遅延させてやればいい template <class T> class stream{ … }; template <class S, class F> class filter_stream{ public: typedef S::elem_type elem_type; filter_stream(S &s, F f=F()): s(s), f(f) {} elem_type get(){ for (;;){ elem_type r=s.get(); if (f(r)) return r; } } };
遅延ストリーム(2) template <class
S, class F> class map_stream{ public: typedef S::elem_type elem_type; map_stream(S &s, F f=F()): s(s), f(f) {} elem_type get(){ elem_type r=s.get(); return f(r); } }; stream<int> s; filter_stream<typeof(s), is_even> t(s); map_stream<typeof(t), div2> u(t); while(!u.empty()) cout<<u.get()<<endl;
インライン化 テンプレートで書かれているので
インライン化できる 1パスでできる stream<int> s; filter_stream<typeof(s), is_even> t(s); map_stream<typeof(t), div2> u(t); u.get(); // => r=t.get(); return div2(r); // => int r; for (;;){ r=s.get(); if (!is_even(r)) break; } // return div2(r);
yieldとの対比
C#でのyield class FilterStream{ public FilterStream( … ) { … } public IEnumerator<int> GetEnumerator(){ foreach (int t in s) if (!f(t)) yield return i; } … ループを回すだけのようなことなら 同じようにできる
コルーチン=遅延評価 yield=コルーチンで遅延評価はできる 遅延評価でyieldのようなこともできる
列挙のようなときにはうまくいく
まとめ
C++の謎テクをいくつか紹介 ブロック=継続 Serializable=Reflectable コルーチン=遅延評価 pficommon近日リリース予定
Advertisement