lexical_castと戻り値の型推論
最近、型ルーズな言語や、型推論してくれる言語ばかりいじっていたので、ものすごく怠惰になっている自分に気がつく。発端は「C++でsscanf()とかatoi()とか使いたくないけど、stringstreamつかうのめんどいよー」とつぶやいたら、「それ boost::lexical_castで」と教えてもらって、大変大喜びなどしたこと。
#include <iostream> #include <boost/lexical_cast.hpp> #include <string> using namespace std; using namespace boost; main() { int sum = 0; string input; while (cin >> input) sum += lexical_cast<int>(input); cout << sum << endl; }
しかし、怠惰脳にはこの
sum += lexical_cast<int>(input);
の
ふとここで、キャスト演算子、という言葉が頭をよぎる。キャスト演算子って言うのを始めて知ったのは随分前なんだけど、うろ覚えにtemplate張れた覚えがある。これを張れば自動キャストできないだろうか、とゆー感じ。
要はもう一個中間のクラスXを作って、そいつがtemplateつきのキャスト演算子をオーバーライド。そこでlexical_cast<>()させる。で、キャスト用関数はこのXを返す。するとコンテキストで暗黙の型変換が起こってハッピー、というシナリオ。
やってみる
include <iostream> #include <boost/lexical_cast.hpp> #include <string> using namespace std; using namespace boost; template<typename T> class X { T t ; public: X(T t): t(t) {} template <typename To> operator To() { return lexical_cast<To>(t); } }; template <typename T> X<T> cast(T t) { return t; } main() { int sum = 0; string input; while (cin >> input) { int val = cast(input); sum += val; // sum += cast(input); では駄目だった。うーむ } cout << sum << endl; }
良いッぽいが、コメントにも書いたように += 演算子だと駄目っぽい。うーん。
とりあえず自動でキャストできるようにはなったけど、高々
素直に変換先を書いたほうが pedantic 的なことが良いという意味でよいのかもしれないなーとか思った。