Enviar búsqueda
Cargar
Iterators must-go(ja)
•
1 recomendación
•
2,037 vistas
Akira Takahashi
Seguir
Denunciar
Compartir
Denunciar
Compartir
1 de 50
Descargar ahora
Descargar para leer sin conexión
Recomendados
iterators-must-go
iterators-must-go
Hiroshi Ono
Boost.PropertyMap (.pdf)
Boost.PropertyMap (.pdf)
Cryolite
Java8から17へ
Java8から17へ
onozaty
10のJava9で変わるJava8の嫌なとこ!
10のJava9で変わるJava8の嫌なとこ!
bitter_fox
リテラル文字列型までの道
リテラル文字列型までの道
Satoshi Sato
Tdd
Tdd
Takaya Kotohata
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
Ransui Iso
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
Genya Murakami
Más contenido relacionado
Similar a Iterators must-go(ja)
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研
dmcc2015
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
CHY72
DTrace for biginners part(2)
DTrace for biginners part(2)
Shoji Haraguchi
Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
Takaaki Tanaka
中3女子でもわかる constexpr
中3女子でもわかる constexpr
Genya Murakami
続・ゲンバのSwift
続・ゲンバのSwift
Yuichi Adachi
Constexpr 中3女子テクニック
Constexpr 中3女子テクニック
Genya Murakami
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
Tsukasa Oi
JavaScriptクイックスタート
JavaScriptクイックスタート
Shumpei Shiraishi
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
Kohsuke Yuasa
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka
A Multiple Pairs Shortest Path Algorithm 解説
A Multiple Pairs Shortest Path Algorithm 解説
Osamu Masutani
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
mametter
php7's ast
php7's ast
do_aki
AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説
AtCoder Inc.
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)
Masahiro Hayashi
C++0x 言語の未来を語る
C++0x 言語の未来を語る
Akira Takahashi
C言語講習会2
C言語講習会2
odenhadengaku
Scala による自然言語処理
Scala による自然言語処理
Hiroyoshi Komatsu
PHP AST 徹底解説
PHP AST 徹底解説
do_aki
Similar a Iterators must-go(ja)
(20)
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
DTrace for biginners part(2)
DTrace for biginners part(2)
Enumはデキる子 ~ case .Success(let value): ~
Enumはデキる子 ~ case .Success(let value): ~
中3女子でもわかる constexpr
中3女子でもわかる constexpr
続・ゲンバのSwift
続・ゲンバのSwift
Constexpr 中3女子テクニック
Constexpr 中3女子テクニック
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
リバースエンジニアリングのための新しいトレース手法 - PacSec 2010
JavaScriptクイックスタート
JavaScriptクイックスタート
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
A Multiple Pairs Shortest Path Algorithm 解説
A Multiple Pairs Shortest Path Algorithm 解説
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
型プロファイラ:抽象解釈に基づくRuby 3の静的解析
php7's ast
php7's ast
AtCoder Beginner Contest 007 解説
AtCoder Beginner Contest 007 解説
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)
C++0x 言語の未来を語る
C++0x 言語の未来を語る
C言語講習会2
C言語講習会2
Scala による自然言語処理
Scala による自然言語処理
PHP AST 徹底解説
PHP AST 徹底解説
Más de Akira Takahashi
Cpp20 overview language features
Cpp20 overview language features
Akira Takahashi
Cppmix 02
Cppmix 02
Akira Takahashi
Cppmix 01
Cppmix 01
Akira Takahashi
Modern C++ Learning
Modern C++ Learning
Akira Takahashi
cpprefjp documentation
cpprefjp documentation
Akira Takahashi
C++1z draft
C++1z draft
Akira Takahashi
Boost tour 1_61_0 merge
Boost tour 1_61_0 merge
Akira Takahashi
Boost tour 1_61_0
Boost tour 1_61_0
Akira Takahashi
error handling using expected
error handling using expected
Akira Takahashi
Boost tour 1.60.0 merge
Boost tour 1.60.0 merge
Akira Takahashi
Boost tour 1.60.0
Boost tour 1.60.0
Akira Takahashi
Boost container feature
Boost container feature
Akira Takahashi
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
Akira Takahashi
Boost Tour 1_58_0
Boost Tour 1_58_0
Akira Takahashi
C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
Akira Takahashi
C++14 enum hash
C++14 enum hash
Akira Takahashi
Multi paradigm design
Multi paradigm design
Akira Takahashi
Start Concurrent
Start Concurrent
Akira Takahashi
Programmer mind
Programmer mind
Akira Takahashi
Boost.Study 14 Opening
Boost.Study 14 Opening
Akira Takahashi
Más de Akira Takahashi
(20)
Cpp20 overview language features
Cpp20 overview language features
Cppmix 02
Cppmix 02
Cppmix 01
Cppmix 01
Modern C++ Learning
Modern C++ Learning
cpprefjp documentation
cpprefjp documentation
C++1z draft
C++1z draft
Boost tour 1_61_0 merge
Boost tour 1_61_0 merge
Boost tour 1_61_0
Boost tour 1_61_0
error handling using expected
error handling using expected
Boost tour 1.60.0 merge
Boost tour 1.60.0 merge
Boost tour 1.60.0
Boost tour 1.60.0
Boost container feature
Boost container feature
Boost Tour 1_58_0 merge
Boost Tour 1_58_0 merge
Boost Tour 1_58_0
Boost Tour 1_58_0
C++14 solve explicit_default_constructor
C++14 solve explicit_default_constructor
C++14 enum hash
C++14 enum hash
Multi paradigm design
Multi paradigm design
Start Concurrent
Start Concurrent
Programmer mind
Programmer mind
Boost.Study 14 Opening
Boost.Study 14 Opening
Iterators must-go(ja)
1.
Iterators Must Go
Andrei Alexandrescu ©2009 Andrei Alexandrescu
2.
This Talk •
The STL • Iterators • Range-based design • Conclusions ©2009 Andrei Alexandrescu
3.
STLとは何か? ©2009 Andrei Alexandrescu
4.
STLとは何か? • アルゴリズムとデータ構造の(良い|悪い|醜い)ライブラリ
• iterators = gcd(containers, algorithms); • Scrumptious Template Lore(すばらしいテンプレートの知恵) • Snout to Tail Length(先頭から最後尾までの長さ) ©2009 Andrei Alexandrescu
5.
STLとは何かというと • STLでは答えよりも質問の方が重要
• “基本的なコンテナとアルゴリズムの中で最も一般的な 実装はどのようなものでしょうか?” • ほかのものは全てその余波 • STLで最も重要なこと: STLはひとつの答えではあるが、答えではない ©2009 Andrei Alexandrescu
6.
STLは非直観的 • 相対性理論が非直観的なのと同じ方向
• 複素数が非直観的なのと同じ方向 n√-1形式の値は”虚数”だが 方程式で使用することができる。 ©2009 Andrei Alexandrescu
7.
非直観的 • “私は最も一般的なアルゴリズムを設計したい。”
• “もちろんできる。あなたが確実に必要とするものは、イテレータと呼ばれ るものである。正確に言うとそれらのうちの5つ。” • 証拠:どんな言語も”たまたま”STLをサポートしなかった。 • 無慈悲な”機能戦争”にもかかわらず • C++とDが唯一 • どちらもSTLのサポートを積極的に目指した • 結果:STLは、C++とDの外から理解するのが非常に困難になった。 ©2009 Andrei Alexandrescu
8.
Fundamental vs Incidental
in STL (基礎 vs 偶発的なSTL) • F:アルゴリズムは可能な限り狭いインタフェースで定義される • F:アルゴリズムに必要とされる広いイテレータカテゴリ • I:iterator primitiveの選択 • I:iterator primitiveの構文 ©2009 Andrei Alexandrescu
9.
STL:良い点 • 正しい質問ができる
• 一般的 • 効率的 • 無理なく拡張可能 • 組み込み型に統合された ©2009 Andrei Alexandrescu
10.
STL:悪い点 • ラムダ関数のサポートが貧弱
• STLの問題ではない • 高い機会費用 • いくつかのコンテナはサポートできない – たとえば、sentinel-terminatedコンテナ – たとえば、分散ストレージを持つコンテナ • いくつかの反復法はサポートできない ©2009 Andrei Alexandrescu
11.
STL:醜い点 • for_each等の試みは助けにならなかった
• ストリームによる統合が希薄 • 1単語:allocator • イテレータの最低なところ – 冗長 – 安全ではない – 貧弱なインタフェース ©2009 Andrei Alexandrescu
12.
イテレータの取り決めは何か? ©2009 Andrei Alexandrescu
13.
Iterators Rock •
コンテナとアルゴリズム間の相互作用をまとめ上げる • “強度低下:”m・nの代わりにm+nを実装 • 拡張可能:ここで、STLが日の目を見て以来、イテレータに動 揺が走った ©2009 Andrei Alexandrescu
14.
危険信号 #1 •
2001年頃にC++ Users Journalは広告キャンペーンを行った – 「CUJに記事を投稿してください!」 – 「英文学を専攻している必要はありません! エディタで始めてください!」 – 「私たちはセキュリティ、ネットワーク技術、C++技術、その他の技術に 興味があります!」 注:まだ他のイテレータには興味がありませんでした • 公開されたイテレータはどれくらい生き残った? ©2009 Andrei Alexandrescu
15.
危険信号 #2 •
およそ1975年のファイルコピー #include <stdio.h> int main() { int c; while ((c = getchar()) != EOF) putchar(c); return errno != 0; } ©2009 Andrei Alexandrescu
16.
危険信号 #2 •
20年ほど早送りして… #include <iostream> #include <algorithm> #include <iterator> #include <string> using namespace std; int main() { copy(istream_iterator<string>(cin), istream_iterator<string>(), ostream_iterator<string>(cout,"¥n")); } ©2009 Andrei Alexandrescu
17.
(mainの中にtry/catchを書くのを忘れた) ©2009 Andrei Alexandrescu
18.
(何かどこか、逆にひどくなってしまった) ©2009 Andrei Alexandrescu
19.
危険信号 #3 •
イテレータは定義するのが非常に難しい • かさばった実装と多くの了解事項(gotcha) • Boostはイテレータの定義を支援する完全なライブラリを含ん でいる • 本質的なプリミティブは…3つ? – 終了(At end) – アクセス(Access) – 衝突(Bump) ©2009 Andrei Alexandrescu
20.
危険信号 #4 •
イテレータはポインタの構文とセマンティクスを使用する • 勝利/敗北のポインタとの統合 • しかし、これはイテレーションの方法を制限する – パラメータを持った++が必要なので、深いツリーを歩かせることがで きない – OutputIteratorはひとつの型しか受け取ることができない: それらは全て同じ場所へ行くが、output_iteratorは出力するそれぞれ の型でパラメータ化されなければならない ©2009 Andrei Alexandrescu
21.
最終的な命取り • 全てのイテレータプリミティブは基本的に安全ではない
• ほとんどのイテレータは、与えられたイテレータのために – 比較できるかどうかを記述することができない – インクリメントできるかどうかを記述することができない – 間接参照できるかどうかを記述することができない • 安全なイテレータを書くことができる – 高いサイズ+速度のコストで – たいていは、設計をカットできなかったというよい議論 (訳注:かなり怪しい訳) ©2009 Andrei Alexandrescu
22.
Range ©2009 Andrei Alexandrescu
23.
Enter Range •
これらの不便さを部分的に回避するため、 Rangeが定義された • Rangeは、begin/endイテレータの組をパックしたもの • そのため、Rangeはより高レベルのcheckable invariant(訳注: チェック可能な不変式?)を持つ • BoostとAdobeのライブラリはRangeを定義した ©2009 Andrei Alexandrescu
24.
それらはよい方向におもしろい一歩を踏み出した ©2009 Andrei Alexandrescu
25.
より一層理解されなけばならない ©2009 Andrei Alexandrescu
26.
ほら、どこにもイテレータがない! • イテレータの代わりにRangeをイテレーション用の
基本構造として定義してはどうだろう? • Rangeは、イテレーションに依存しない基本処理を定義するべき • 今後イテレータはなく、Rangeだけが残るだろう(訳注:怪しい) • Rangeはどのプリミティブをサポートしなければならないか begin/endがオプションではないことを思い出してほしい 人々が個々のイテレータを貯め込んでいたら、我々は振り出しに戻らなければならない ©2009 Andrei Alexandrescu
27.
Rangeの定義 • <algorithm>は全てRangeで定義でき、他のアルゴリズムも同様にRangeで
実装できる • Rangeプリミティブは、少ないコストでチェック可能でなければならない • イテレータより非効率であってはならない ©2009 Andrei Alexandrescu
28.
Input/Forward Range
template<class T> struct InputRange { bool empty() const; void popFront(); T& front() const; }; ©2009 Andrei Alexandrescu
29.
証明可能? template<class T>
struct ContigRange { bool empty() const { return b >= e; } void popFront() { assert(!empty()); ++b; } T& front() const { assert(!empty()); return *b; } private: T *b, *e; }; ©2009 Andrei Alexandrescu
30.
検索 // オリジナル版のSTL
template<class It, class T> It find(It b, It e, T value) { for (; b != e; ++b) if (value == *b) break; return b; } ... auto i = find(v.begin(), v.end(), value); if (i != v.end()) ... ©2009 Andrei Alexandrescu
31.
設計質問 • Rangeでのfindはどのように見えなければならないか?
1. 範囲のひとつの要素(見つかった場合)、 もしくは0個の要素(見つからなかった場合)を返す? 2. 見つかった要素以前のRangeを返す? 3. 見つかった要素以降のRangeを返す? • 正解:(もしあった場合)見つかった要素で始まるRangeを返し、そうでなければ空 を返す なぜ? ©2009 Andrei Alexandrescu
32.
検索 // Rangeを使用
template<class R, class T> R find(R r, T value) { for (; !r.empty(); r.popFront()) if (value == r.front()) break; return r; } ... auto r = find(v.all(), value); if (!r.empty()) ... ©2009 Andrei Alexandrescu
33.
エレガントな仕様
template<class R, class T> R find(R r, T value); 「frontがvalueと等しいか、rが使い尽くされるまで、 左から範囲rを縮小する」 ©2009 Andrei Alexandrescu
34.
Bidirectional Range
template<class T> struct BidirRange { bool empty() const; void popFront(); void popBack(); T& front() const; T& back() const; }; ©2009 Andrei Alexandrescu
35.
Reverse Iteration template<class
R> struct Retro { bool empty() const { return r.empty(); } void popFront() { return r.popBack(); } void popBack() { return r.popFront(); } E<R>::Type& front() const { return r.back(); } E<R>::Type& back() const { return r.front(); } R r; }; template<class R> Retro<R> retro(R r) { return Retro<R>(r); } template<class R> R retro(Retro<R> r) { return r.r; // klever(訳注:clever? : 賢いところ) } ©2009 Andrei Alexandrescu
36.
find_endはどうだろう?
template<class R, class T> R find_end(R r, T value) { return retro(find(retro(r)); } • rbegin, rendは必要ない • コンテナは、範囲を返すallを定義する • 後ろにイテレートする:retro(cont.all()) ©2009 Andrei Alexandrescu
37.
イテレータでのfind_endは最低だ
// reverse_iteratorを使用したfind_end template<class It, class T> It find_end(It b, It e, T value) { It r = find(reverse_iterator<It>(e), reverse_iterator<It>(b), value).base(); return r == b ? e : --r; } • Rangeが圧倒的に有利:はるかに簡潔なコード • 2つを同時に扱うのではなく、1つのオブジェクトのみから構 成されるので、容易な構成になる ©2009 Andrei Alexandrescu
38.
さらなる構成の可能性 • Chain
: いくつかのRangeをつなげる 要素はコピーされない! Rangeのカテゴリは、全てのRangeの中で最も弱い • Zip : 密集行進法(lockstep)でRangeを渡る Tupleが必要 • Stride : 一度に数ステップ、Rangeを渡る イテレータではこれを実装することができない! • Radial : 中間(あるいはその他のポイント)からの距離を増加させる際に Rangeを渡る ©2009 Andrei Alexandrescu
39.
3つのイテレータの関数はどうだろうか? template<class It1,
class It2> void copy(It1 begin, It1 end, It2 to); template<class It> void partial_sort(It begin, It mid, It end); template<class It> void rotate(It begin, It mid, It end); template<class It, class Pr> It partition(It begin, It end, Pr pred); template<class It, class Pr> It inplace_merge(It begin, It mid, It end); ©2009 Andrei Alexandrescu
40.
「困難なところにはチャンスがある。」
"Where there's hardship, there's opportunity." – I. Meade Etop ©2009 Andrei Alexandrescu
41.
3-legged algos ⇒
mixed-range algos template<class R1, class R2> R2 copy(R1 r1, R2 r2); • 仕様:r1からr2へコピーして、手をつけていないr2を返す vector<float> v; list<int> s; deque<double> d; copy(chain(v, s), d); ©2009 Andrei Alexandrescu
42.
3-legged algos ⇒
mixed-range algos template<class R1, class R2> void partial_sort(R1 r1, R2 r2); • 仕様:最も小さな要素がr1の中で終了するように、r1とr2の連結を 部分的にソートする • あなたは、vectorとdequeをとり、両方の中で最も小さな要素を配列に入 れることができる vector<float> v; deque<double> d; partial_sort(v, d); ©2009 Andrei Alexandrescu
43.
ちょっと待って、まだある
vector<double> v1, v2; deque<double> d; partial_sort(v1, chain(v2, d)); sort(chain(v1, v2, d)); • アルゴリズムは今、余分な労力なしで任意のRangeの組み合わせにおい ても途切れることなく動作することができる • イテレータでこれを試してみて! ©2009 Andrei Alexandrescu
44.
ちょっと待って、さらにある
vector<double> vd; vector<string> vs; // 密集行進法(lockstep)で2つをソートする sort(zip(vs, vd)); • Rangeコンビネータは、無数の新しい使い方ができるようになる • イテレータでも理論上は可能だが、(再び)構文が爆発する ©2009 Andrei Alexandrescu
45.
Output Range
• ポインタ構文からの解放されたので、異なる型をサポートすることが可能になった struct OutRange { typedef Typelist<int, double, string> Types; void put(int); void put(double); void put(string); }; ©2009 Andrei Alexandrescu
46.
stdinからstdoutにコピーする話に戻ろう
#include <...> int main() { copy(istream_range<string>(cin), ostream_range(cout, "¥n")); } 1 • 最後にもう一歩:1行(one-line)に収まる寸言 (one-liner) • ostream_rangeにはstringを指定する必要はない 1 スライド制限にもかかわらず ©2009 Andrei Alexandrescu
47.
Infinite Range(無限の範囲) •
無限についての概念はRangeでおもしろくなる • ジェネレータ、乱数、シリーズ、… はInfinite Range • 無限は、5つの古典的カテゴリとは異なる特性; あらゆる種類のRangeが無限かもしれない • ランダムアクセスなRangeさえ無限かもしれない! • 無限について静的に知っておくことは、アルゴリズムを助ける ©2009 Andrei Alexandrescu
48.
has_size • Rangeが効率的に計算されたsizeを持っているかどうかは他の独立した特
性 • 索引項目:list.size, 永遠の討論 • Input Rangeさえ、既知のサイズを持つことができる (たとえば、100個の乱数をとるtake(100, rndgen)) – rが無限の場合、take(100, r)は100の長さ – rが長さを知っている場合、長さはmin(100, r.size()) – rが未知の長さで有限の場合、未知の長さ ©2009 Andrei Alexandrescu
49.
予想外の展開(A Twist) •
Rangeで<algorithm>をやり直すことができる? • Dのstdlibは、std.algorithmとstd.rangeモジュールで<algorithm>のスー パーセットを提供している(googleで検索してほしい) • RangeはD全体に渡って利用されている: アルゴリズム、遅延評価、乱数、高階関数、foreach文… • いくつかの可能性はまだ簡単には挙げられなかった – たとえばfilter(input/output range) • Doctor Dobb‘s Journalの「The Case for D」をチェックしておいてください。 coming soon... ©2009 Andrei Alexandrescu
50.
結論 • Rangeは優れた抽象的概念である
• より良いチェック能力(まだ完全ではない) • 容易な構成 • Rangeに基づいた設計は、イテレータに基づいた関数をはるかに超えるも のを提供する • 一歩進んだSTLによる刺激的な開発 ©2009 Andrei Alexandrescu
Descargar ahora