Policyをboost::function+boost:bindで
前はpolicyでやってたのだが,いちいちオブジェクトを作る作業が大仰すぎると感じた.
Policyをメンバ関数ポインタで - ...ing logging 3.0
そこでメンバ関数ポインタを使ってみた.
の続き.
メンバ関数ポインタは型がややこしいから嫌だった.
delegateがあればいいのに・・・と思ってたら,とあることを思い出した.
そうだ,boost::function+boost::bindがあった.
#include <iostream> using namespace std; #include <boost/function.hpp> #include <boost/bind.hpp> using namespace boost; // 本来はどこかで定義されているものたち typedef int HWND; void MouseCapture(HWND){} void ReleaseCapture(){} HWND GetHWnd(){return 0;} class mouse_event_logger { public: void on_left_button_down(){cout << "LeftButtonDown" << endl;} void on_left_button_up(){cout << "LeftButtonUp" << endl;} void on_right_button_down(){cout << "RightButtonDown" << endl;} void on_right_button_up(){cout << "RightButtonUp" << endl;} //... }; void f(function<void()> mouse_capture, function<void()> logger_method, bool enabled) { mouse_capture(); if (enabled) logger_method(); }; class context { bool enabled; mouse_event_logger logger; public: context() : enabled(false) {} void set_enabled(bool b) {enabled = b;} // 同じようなメソッドがたくさん出てくるのでまとめたいけれど // 型の違いではないからtemplateではうまくまとめられない? void on_left_button_down(HWND hwnd) { ::MouseCapture(hwnd); if (enabled) logger.on_left_button_down(); } void on_left_button_up() { ::ReleaseCapture(); if (enabled) logger.on_left_button_up(); } // こうだ! void on_right_button_down(HWND hwnd) { f(bind(::MouseCapture, hwnd), bind(&mouse_event_logger::on_right_button_down, &logger), enabled); } void on_right_button_up() { f(::ReleaseCapture, bind(&mouse_event_logger::on_right_button_up, &logger), enabled); } }; int main() { context c; c.set_enabled(true); c.on_left_button_down(GetHWnd()); c.on_left_button_up(); c.on_right_button_down(GetHWnd()); c.on_right_button_up(); return 0; }
ReleaseCaptureHelper()も自然になくなった.
心配なのは実行速度くらい.
最適化で展開されたりするのかな.
追記
ちなみにオブジェクトを作る作業が大仰というのは,クラスを定義することも含めての話.