boost::optionalを使ってみて 第一回
boost::optionalを使ってみて 第一回
boost::optionalをやってみました.C++でOption型を実現する例のアレ.
scalaのmatch caseがあまりに便利なので同等のものがほしかったのだけど,結局冗長に書くことでしか実現できなそう.
第一回ということは,まだあきらめてないのです,一応.
boost::optionalで容易に多相を実現できない
どこか,昔の彼方で見たときは,確かboost::optional
地雷1:仮に想像通りの仕様だったとしても,C++の変数は次のようにauto宣言で,二つの状態を持たすことができない.
boos::optional<int> hoge = Noneか実数値; auto type = ([](auto x){if(x){return *x;}else{return nullptr;};})(hoge);//lambdaのauto xは多相になりうるが,変数のtypeは多相にできない.
地雷2:コンパイル時に多相が確定するほど,boostの実装は楽でない.
結局scalaのようなsyntax sugerを実現するには,相当な努力が必要
TODOとして以下のものを残した.
TODOを解決したとしても,楽なプロシージャになる気がしない
- templateで'boost::option
- 実行時の返り値の型が多相にならざる得ないので,返り値を束縛して保持するように第2引数はstd::function<void()> = std::bind(lambdaプロシージャ, lamdbaの中で処理する値の戻り値の参照かポインタ)を行う
- 全体的に使用時のシンタックスがわかりやすくなるように加工
進捗 level1
C++1yの新規格で関数内関数で型に応じた書き方ができなかったのが大きい.
コンパイラをclangに変えたのだが,llvmのエラーが読めん.
#include<boost/optional.hpp> namespace KOKUU2{ namespace Match{ template<class T> //すべてのevalに対してstd::bindで形成したstd::funtionを引数にとる void eval(T t){ std::cout << "default call" << std::endl;}; template<> void eval<std::nullptr_t>(std::nullptr_t t){ std::cout << "nullptr_t-type call:" << std::endl;}; template<> void eval<int>(int i){ std::cout << "int-type call:" << i << std::endl;}; template<> void eval<boost::optional<int>>(boost::optional<int> x){ //ここを抽象化 std::cout << "boost::optional<int>-type call:" << std::endl; std::cout << "try to get real instance..." << std::endl; if(x){ eval(*x); }else{ eval(nullptr); } }; }; }; int main(int argc, char const *argv[]) { boost::optional<int> aaa = 10; boost::optional<int> bbb = boost::none; int ccc = 99; KOKUU2::Match::eval(aaa); KOKUU2::Match::eval(bbb); KOKUU2::Match::eval(ccc); }
...なんか,行ける気がしてきた