64
boost – std - C# 株株株株 Codeer 株株株株 http://www.codeer.co.j p /

boost - std - C#

Embed Size (px)

Citation preview

Page 1: boost - std - C#

boost – std - C#

株式会社 Codeer石川達也http://www.codeer.co.jp/

Page 2: boost - std - C#

石川達也

株式会社 Codeer 代表取締役

Microsoft MVP for C#

C++ は嗜む程度

自己紹介

Page 3: boost - std - C#

3

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

Java

C++

C

C#

プログラム経験はこんな感じです。

入社

会社辞める→フリー

Codeer 設立

Page 4: boost - std - C#

4

1999 Boost - 1999/12/30(Early releasesが 14日にあった )

2000

2001

2002 Let’s Boostスタート2003

2004 Boost本2005

2006

2007

2008

2009

2010

2011 C++11

2012

2013

2014

Page 5: boost - std - C#

5

1999 Boost - 1999/12/30(Early releasesが 14日にあった )

2000 C#発表 (6月 )

2001

2002 Let’s Boostスタート2003 C#1.1

2004 Boost本2005 C#2.0(11月 )

2006

2007

2008

2009

2010

2011 C++11

2012

2013

2014

Page 6: boost - std - C#

6

あれは 2005 年の春すっかり Java にかぶれていたころ・・・

久しぶりに C++ の仕事に就くことになりました。

Java サイコー

Page 7: boost - std - C#

7

なんじゃこりゃー!めっちゃメモリリークしとるやんけ!

こんな複雑なコードで new deleteやったら、そらリークするわな・・・。

大規模アプリ開発はGC なしではやってられ

まへん

Page 8: boost - std - C#

8

Boost との遭遇 – shared_ptr-

え、メモリ管理しなくていいの?

shared_ptr というのがあってだね

Page 9: boost - std - C#

9

Boost との遭遇 – shared_ptr-

説明不要!みんな大好き shared_ptr !

保持者がいなくなったら、破棄してくれる。GC より厳密なタイミングで破棄!

もちろん C++11 で標準に入っています。

Page 10: boost - std - C#

10

Boost との遭遇 – shared_ptr-

みんな大好き shared_ptr !

デリータを覚えているから dll の壁を越えられる

Shared_ptr

HeapHeap

Page 11: boost - std - C#

11

Boost との遭遇 – shared_ptr-

標準に入れなかった子もいました。shared_array

// これダメ デストラクタが呼ばれないboost::shared_ptr<A> a(new A[3]);

//delete[] が呼ばれるboost::shared_array<A> a(new A[3]);

Page 12: boost - std - C#

12

Boost との遭遇 – shared_ptr-

標準に入れなかった子もいました。shared_array

// こう書くんだってさstd::shared_ptr<A> a(   new A[3],   std::default_delete<A[]>());

Page 13: boost - std - C#

13

Boost との遭遇

他にもいくつか使ったけど、やっぱり shared_ptr がダントツの使用率でした。

Page 14: boost - std - C#

14

時は流れ・・・・

すっかり C++ できる気になってたころ・・・

テンプレートライブラリつくったぜー。  ↑読み返す気が起きない

やっぱ pimpl だよねー。  ↑変な書き方で読みづらい

ネイティブ以外ありえないよねー。  ↑根拠なし

Page 15: boost - std - C#

15

C# に出会いました!

え、中間言語になるの?

そんな軟弱なものやる気がおきんなー。

2007 年の暑い夏の日・・・

Page 16: boost - std - C#

16

C# に出会いました!

なんじゃこりゃー書きやすい意外に速いC# サイコー!

でも、 Generic は・・・

2.0 だったけど

Page 17: boost - std - C#

17

C# に出会いました!

あれ、だったら同じ .Net 使えるC++/CLI とかもっと良いんじゃね?

Page 18: boost - std - C#

18

C# に出会いました!

・・・・

やっぱ C# サイコー

Page 19: boost - std - C#

19

C# に出会いました!

foreach

object 型

delegate

これ C++ でも使えたらいいのにね

Page 20: boost - std - C#

20

これ C++ でも使えたらいいのにね

foreach

object 型

delegate

Page 21: boost - std - C#

21

foreach

BOOST_FOREACH

まさかのマクロで実装!

std::vector<A> vec; BOOST_FOREACH(A e, vec) {}

Page 22: boost - std - C#

22

foreach

std::vector<A> vec; BOOST_FOREACH(A e, vec) {}

// 参照も OKBOOST_FOREACH(A& e, vec) {}BOOST_FOREACH(const A& e, vec) {}

BOOST_FOREACH

Page 23: boost - std - C#

23

foreach

// これはコンパイル通らないstd::map<int, int> m;BOOST_FOREACH( std::map<int, int>::value_type e, m) {}

BOOST_FOREACH

マクロだから , に弱い

Page 24: boost - std - C#

24

foreach

BOOST_FOREACH

// これなら OKtypedef std::map<int, int> Map;Map m;BOOST_FOREACH( Map::value_type e, m) {}

Page 25: boost - std - C#

25

foreach

std::vector<A> vec; for(auto e : vec) {}

// 参照も OKfor(const auto e : vec) {}for(const auto& e : vec) {}

C++11 では

11 では auto って書く方がオシャレ

Page 26: boost - std - C#

26

foreach

MS 方言 for each

for each(A a in vec){}

C++11 以前でも使えてた!

Page 27: boost - std - C#

27

foreach

for each(A a in vec){}

//const 参照も OKfor each(const A& a in vec){}

MS 方言 for each

Page 28: boost - std - C#

28

foreach

MS 方言 for each

for each(A a in vec){}

//const 参照も OKfor each(const A& a in vec){}

// 参照はコンパイル通らない・・・ (´ ・ω ・` )for each(A& a in vec){}

Page 29: boost - std - C#

29

interface

役に立つ MS 方言講座

//class の代わりに interface って書ける!interface IA{public: virtual ~IA(){} virtual void Func() = 0;};

interface であることを強調・・・

Page 30: boost - std - C#

30

property が使える

役に立つ MS 方言講座

class A{ int b;public: int GetB() const { return b; } void SetB(int val) { b = val; }public: __declspec(property( get = GetB, put = SetB)) int B;};

Page 31: boost - std - C#

31

property が使える

役に立つ MS 方言講座

#define PROPERTY( _t, _m ) \private: _t m_##_m ; \public: \ __declspec(property(get=get##_m, put=set##_m)) _t _m ; \ _t get##_m() { return m_##_m; } \ void set##_m( _t value ) { m_##_m = value; };

マクロを作ると書きやすい↓ のサイトに書いてたよ

http://www.moonmile.net/blog/archives/3557

Page 32: boost - std - C#

3232

property が使える

役に立つ MS 方言講座

class A{ PROPERTY( int, B);};

PROPERTY( int, Number );

こんな感じ

Page 33: boost - std - C#

33

property が使える

役に立つ MS 方言講座

A a;a.B = 100;

使う側では便利かも

Page 34: boost - std - C#

34

event

役に立つ MS 方言講座

struct A { __event void Func();};

Page 35: boost - std - C#

35

event

役に立つ MS 方言講座

struct B { A* pA; void Func(){} B(A& a) : pA(&a) { __hook(&A::Func, pA, &B::Func, this); } ~B() { __unhook(&A::Func, pA, &B::Func, this); }};

Page 36: boost - std - C#

36

これ C++ でも使えたらいいのにね

foreach

object 型

delegate

Page 37: boost - std - C#

37

object 型

// 何でも入るよーint i = 0;long l = 1;boost::any a = i;a = l;

boost::any

Page 38: boost - std - C#

38

object 型

// 型情報も取れちゃうif (a.type() == typeid(long)) {}else if (a.type() == typeid(int)) {}

boost::any

Page 39: boost - std - C#

39

object 型

// キャストで中身取得l = boost::any_cast<long>(a);

// 失敗したら例外try {

i = boost::any_cast<int>(a);}catch (boost::bad_any_cast e){}

boost::any

Page 40: boost - std - C#

40

object 型

//shared_ptr と合わせたらもっとポイよねーboost::any a = std::make_shared<X>();

boost::any

便利だけど、標準化はされてないよね?

Page 41: boost - std - C#

41

object 型

boost::any

型をボンヤリさせるテクニックはType Erasure って言うんだってboost::shared_ptr とかboost::functionにも使われているらしい。

Page 42: boost - std - C#

42

これ C++ でも使えたらいいのにね

foreach

object 型

delegate

Page 43: boost - std - C#

43

delegate

class Test { int x = 0; public void MyAction() { x = 10; } public void Main() { Action a = MyAction; a(); }}

そもそも何が便利? C#

単なる関数ポインタではなくインスタンスに結びついている

Page 44: boost - std - C#

44

delegate

class Test{ int x; void MyAction(){ x = 10; }public: void Main() { boost::function<void()> a = boost::bind(&Test::MyAction, this); a(); }};

boost::bind

Page 45: boost - std - C#

45

delegate

class Test{ int x; void MyAction(){ x = 10; }public: void Main() { std::function<void()> a = std::bind(&Test::MyAction, this); a(); }};

C++11 では標準の仲間入り!

Page 46: boost - std - C#

46

delegate

int i = 0;Action a = ()=>{ i++;}a();

Assert.AreEqual(i, 1);

そもそも何が便利? C#

ササっと書けるローカル変数取り込める

Page 47: boost - std - C#

47

delegate

using namespace boost::lambda;boost::function<int(int)> a = _1 + 3;int i = a(5);

boost::lambda

なんじゃこりゃ?

Page 48: boost - std - C#

48

delegate

boost::lambda::placeholder1_type& _1 = free1;

boost::lambda

なんじゃこりゃ?

Page 49: boost - std - C#

49

delegate

placeholder1_type

BOOST_LAMBDA_BE(operator+BOOST_LAMBDA_BE(operator-BOOST_LAMBDA_BE(operator*BOOST_LAMBDA_BE(operator/・・・・

boost::lambda

こいつが operator hogeを山ほど実装しとるわけですな

Page 50: boost - std - C#

50

delegate

boost::function<int(int)> a =

//operator + が実行され、// 関数オブジェクトが返るのでした。_1 + 3;

つまり、引数ありで、一文のみ。

boost::lambda

Page 51: boost - std - C#

51

delegate

int i = 0;auto a = [&](){ i++;};a();

C++11

C++11 なら言語でサポートされている

Page 52: boost - std - C#

52

LINQ

LINQ も重要なんだけど、それを実現するための機能の方がもっと重要型推論 だって LINQ の戻り値の型書くの嫌ラムダ サラッと処理作って渡せるのがいい

のよ( ここが 98 のアルゴリズムの弱点)

匿名型 任意に抽出したデータを返せる拡張メソッド

あたかも、そのコンテナのメソッドのように使える

これらは LINQ 以外でもヘビーに使われる

Page 53: boost - std - C#

53

LINQ

C++11 では?

型推論 auto

ラムダ 言語サポート匿名型 ・・・・拡張メソッド

・・・・

Page 54: boost - std - C#

54

匿名型

void main() { var a = Decl (() => { return new { x = 1, y = "hoge" }; }); var ret = a();}// 型推論を助けてやらんとあかんけどstatic Func<T> Decl<T>(Func<T> x) { return x;}

そもそも C# では

Page 55: boost - std - C#

55

匿名型

[]() {struct{

int a;} a;return a;

};

C++

できるかと思ったらさすがに怒られた w

Page 56: boost - std - C#

56

C++ で拡張メソッド

そもそも C# ではclass A { public int a{get; set;}}static class Aextensions { public static void X(this A a) { a.a = 100; }}A a;a.X();

Page 57: boost - std - C#

57

C++ で拡張メソッド

実は C++ でもその試みはある!

でも、ちょっと広い心が必要・・・

Page 58: boost - std - C#

58

C++ で拡張メソッド

// 結果から言うとこうなります。A a;a|X();

実は C++ でもその試みはある!

関数オブジェクトと operator演算子で解決した。で、 operator. はないから | を使うらしい。まあ、 | じゃなくても、納得いくものならなんでも・・・

Page 59: boost - std - C#

59

C++ で拡張メソッド

struct A { int a; };

struct XCore {   //③    void operator()(A& a){ a.a = 100; }};//②void operator | (A& a, XCore& b) { b(a); }//①XCore X() { return XCore(); }

a|X();

そこまでしてやりたいんかい!

Page 60: boost - std - C#

60

C++ で拡張メソッド

struct A { int a; };

struct XCore {   //③    void operator()(A& a){ a.a = 100; }};//②void operator | (A& a, XCore& b) { b(a); }//①XCore X() { return XCore(); }

a|X();

そこまでしてやりたいんかい!

Page 61: boost - std - C#

61

C++ で拡張メソッド

vector<int> vec;auto ret = vec

| filtered([](const int &e) {...})| filtered([](const int &x) {...})| transformed([](const int &x) {...});

でもおかげで、メソッドチェーンができます。

こう見るとパイプっぽくてカッコいい!

Page 62: boost - std - C#

62

LINQ

C++11 では?

型推論 auto

ラムダ 言語サポート匿名型 × あかんかった拡張メソッド

まあまあイケル

Page 63: boost - std - C#

63

LINQ

C++11 では?

・ cpplinq・ boost.Range の Oven拡張とかあるんだって

↓ ここに書いてありましたhttp://d.hatena.ne.jp/wordi/20131116/p1

Page 64: boost - std - C#

64

ご清聴ありがとうございました!