暇つぶし
遅延評価のカスタマイズって
言語がサポートすれば簡単にサポートできるはずなのに
なんでそれやってる言語ってみかけないのかね、
なんて思ってたが
最近は私ごときでは
言語オタクとはとても名乗れない状況なので
誰か教えてくれないかななんておもいつつ
C++で実装してみることにした。
(それ自体すでに存在しそうな気もする)
テンプレートパラ−メータへのキャストあたりを
使うと、字面上で普通の変数と区別できなくなってしまうが、
とりあえずそれをやってみる。
クラス名はschemeに習ってpromise。
あとせっかくなので遅延評価じゃなくてスレッドにしてみた。
#include <boost/thread.hpp> #include <iostream> template < class T > class promise { public: template < class F > // T () promise(F f) : thread_(boost::bind( &stub<F>, boost::ref(value_), f )) { } ~promise() { thread_.join(); } operator T () { thread_.join(); return value_; } private: template < class F > static void stub(T& value, F f) { value = f(); } private: T value_; boost::thread thread_; }; int main() { promise<int> p([]()->int{ return std::cin.get(); }); std::cout << (int)p << std::endl; return 0; }
まあなんかそれなりに使えそうな気がしないでもない。
キャストだと字面でわからなくて危険なので、forceとかしてみようか。
T force() {
thread_.join();
return value_;
}
でも字面が面倒だとlambdaをautoで持つのとどう違うのか、という
疑問が生ずるな。
ならいっそのこともっと手を抜いて
template < class R > operator R () { thread_.join(); return static_cast<R>(static_cast<T>(value_)); }
とするか。
気が向いたらcopyableにしとくかな。
内部でthread_pool使うようにしたら
TopCoderでmemoization代わりに使ったりできないかな。