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);

の存在が許せない。これくらい型推論してくれても良いじゃんよー、とか思ってしまう。明白なんだし。と、なくしてみたら駄目であることに気がついた(というかエラー食らった)。C++の深部まで入り込んだことがあまり無いので、これは仕様上「C++の関数テンプレートでは戻り値の型推論はしない」ということらしいことを知らなかった ...... orz
ふとここで、キャスト演算子、という言葉が頭をよぎる。キャスト演算子って言うのを始めて知ったのは随分前なんだけど、うろ覚えに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;
}

良いッぽいが、コメントにも書いたように += 演算子だと駄目っぽい。うーん。
とりあえず自動でキャストできるようにはなったけど、高々を無くすためだけにどんだけ、って感じなのと、やはり cast関数分のコードが生成されてしまう。ので、あんまり意味が無い気もする。
素直に変換先を書いたほうが pedantic 的なことが良いという意味でよいのかもしれないなーとか思った。