Destructive Call

1,800 views
1,728 views

Published on

2011/05/14 Boost

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,800
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Destructive Call

  1. 1. Boost.破壊的関数呼び出し くらいおらいと
  2. 2. 注意「それ○○でできるよ」「それ○○がすでに言ってたよ」と言われた時点で本発表は強制終了します
  3. 3. 前提知識• C++0x –ムーブセマンティクス (右辺値参照) –右辺値参照 on *this• Boost –Boost.Bind –Boost.Thread –Boost.Asio –Boost.ScopeExit
  4. 4. Motivation 下記のコードが通らなくて大変悲しいvoid thread_main(std::unique_ptr<int> p){ …}std::unique_ptr<int> p(new int(42));auto f = boost::bind(&thread_main, std::move(p));boost::thread  th(f); // コンパイルエラー
  5. 5. Motivation 下記のコードが通らなくて大変悲しいvoid thread_main(std::unique_ptr<int> p){ …} このパタン (非同期呼び出しにおける 所有権の移動) は超重要std::unique_ptr<int> p(new int(42));auto f = boost::bind(&thread_main, std::move(p));boost::thread  th(f); // コンパイルエラー
  6. 6. 何が問題か?boost::bind が呼び出し時に束縛された引数をコピーしようとする(+ boost::bind が内部で束縛されたオブジェクトをコピーする) ↓std::unique_ptr はコピーできないのでアボン
  7. 7. 5分で考えたオレオレアイデアboost::thread の実装では,スレッド関数呼び出し時に boost::bind が束縛している引数オブジェクトを破壊しても大丈夫なはずだ
  8. 8. Boost.Thread 内部実装(テキトー)// Boost.Thread の内部実装// thread_callback はコールバック// a1, a2 は引数thread_callback(a1, a2, …);// thread_callback は// これ以降一切呼び出されない
  9. 9. 俺が考えた最強の Boost.Thread 内部実装// Boost.Thread の内部実装// thread_callback はコールバック// a1, a2 は引数std::move(thread_callback)(a1, a2, …);// thread_callback は// これ以降一切呼び出されない
  10. 10. Move とはMove できるMovable +Move を利用するMove‐aware
  11. 11. 破壊的関数呼び出し とは破壊的に呼び出せるDestructivelyCallable +破壊的呼び出しを利用するDestructive‐Call‐aware
  12. 12. boost::bind 側 破壊的に呼び出せるtemplate<…>class bind_wrapper { … template<…> void opeartor()(…) && …};
  13. 13. Boost.Thread 側 破壊的呼び出しを利用する// Boost.Thread の内部実装// thread_callback はコールバック// a1, a2 は残りの引数std::move(thread_callback)(a1, a2, …);
  14. 14. あるコンポーネントが 破壊的呼び出しを利用できる条件指定された callback を破壊的に呼び出してよいのは, callback を高々1回しか呼ばないとき
  15. 15. 破壊的関数呼び出しができる例 = callback を高々1回しか呼ばない例• Boost.Thread• Boost.Asio のイベントハンドラ• スコープガードに指定するコール バック (Boost.ScopeGuard)• (std::async)
  16. 16. 破壊的関数呼び出しのまとめ• Boost.Bind に対して move on *this  による operator() のオーバーロード を追加• Boost.Thread, Boost.Asio,  Boost.ScopeExit の実装の該当箇所 に std::move なパッチを当てる
  17. 17. 破壊的関数呼び出しの利点• 後方互換性を完全に維持したまま, 既存のコンポーネントの適用範囲を 広げる• 特に非同期関数呼び出しにおける 所有権の移動が非常に扱いやすく なる
  18. 18. 今後の予定• 誰も言ってないっぽいなら Boost に Asio と Thread と ScopeGuard のパッ チ付きで提案して殴り込みをかける• 返り討ちにあう• それでもがんばる• move on *this が clang++ にしか実 装されていないのでさようなら(^o^)ノ

×