戻り値受け取り型templateクラス
Win32とかMFCつかっていると戻り値でエラーが-1で定義されているものがあり、
そういうときは、
int ret = GetCurSel(); if( ret == (-1) ) { /* 失敗した */ }
という鈍くさいコード書かないといけません。
なるべく読み手がわかるように書きたい!!ということで作ってみました。
#include <iostream> #include <boost/optional.hpp> using namespace std; template < typename T , T failedValueType > class Result { private: boost::optional<T> val_; public: Result() { } Result(const T& v) : val_( v ) { } operator T() { return val_.get(); } Result& operator = ( const T& other ) { val_ = other; return *this; } bool is_failed() const { // val_が未初期化だとboost::optional内のアサートが // でるので便利 return val_.get() == failedValueType; } }; struct Win32Error { enum { NotCurSel = -1, }; }; typedef Result<int,Win32Error::NotCurSel> Win32Result; int GetCurSel() { return -1; // エラーを返したと仮定して... } int _tmain(int argc, _TCHAR* argv[]) { Win32Result ret(-1); if((ret = GetCurSel()).is_failed()) { std::cout << "失敗しているがな" << std::endl; }else { std::cout << "OKだお" << std::endl; } }
仮に、retで何も受け取らないでおけば、optionalの実装で、get()呼び出し時に、
boost::assertがかかるので便利です。
追記:
id:melponさんからのアドバイス
template
{
Win32Result r = f(); if (r.is_failed()) throw "エラー";/*なんか例外なげとけーー*/ return r;
}
こんなんできるよ。みたいな。