C++ 戻り値の異なる関数 template
先日からやっている .ini やレジストリにアクセスする関数.
MFC の CWinApp::GetProfileString , CWinApp::WriteProfileString にあたる部分は目途がついた.
それで,それらを呼出す部分.前に作成したものもそうだったが,型ごとにクラスの関数を定義していた.
これらをもう少し簡単にできないかと…
set の方は,特に難しい所はない(::To_tstring は,文字列に変換する関数として用意している).
template <class T> bool INI_set (LPCTSTR sec,LPCTSTR ent,const T& val)
{
tstring ini = ::INI_get_module_ini() ;
tstring str = ::To_tstring(val) ;
return ::INI_set(ini.c_str(),sec,ent,str.c_str()) ;
}
get の場合,文字列から変数に変換する方法をどうするか?
例えば,atoi や atof ,他にも 4 つの整数の文字列を RECT に変換するなど.
検索すると template で可能みたい だが…
よくわからなかったので,簡単な方法にした.
inline RECT To_RECT (LPCTSTR str)
{
RECT rect = { 0 } ;
{
v_tstring str_ary = ::String_SplitSpace(str,_T(" ,\t\r\n")) ;
if (0 < str_ary.size()) { rect.left = ::ttoi4(str_ary[0]) ; }
if (1 < str_ary.size()) { rect.top = ::ttoi4(str_ary[1]) ; }
if (2 < str_ary.size()) { rect.right = ::ttoi4(str_ary[2]) ; }
if (3 < str_ary.size()) { rect.bottom = ::ttoi4(str_ary[3]) ; }
}
return rect ;
}
inline bool string_to (LPCTSTR str,RECT* rect_) { *rect_ = ::To_RECT (str) ; return true ; }
inline bool string_to (LPCTSTR str,POINT* point) { *point = ::To_POINT(str) ; return true ; }
inline bool string_to (LPCTSTR str,SIZE* size_) { *size_ = ::To_SIZE (str) ; return true ; }
それぞれの型に合わせた関数を呼べるようになったので template に.
template <class T> T INI_get (LPCTSTR sec,LPCTSTR ent,const T& def)
{
tstring ini = ::INI_get_module_ini() ;
tstring dst = ::To_tstring(def) ;
tstring str = ::INI_get(ini.c_str(),sec,ent,dst.c_str()) ;
T val ;
::string_to(str.c_str(),&val) ;
return val ;
}
これで,次の様な使い方ができる様になる.
{
POINT point = ::POINT_set( 10, 20) ;
SIZE size_ = :: SIZE_set( 1111, 525) ;
RECT rect_ = :: RECT_set(point,size_) ;
{
::INI_set(_T("test"),_T("rect_"),rect_) ;
::INI_set(_T("test"),_T("point"),point) ;
::INI_set(_T("test"),_T("size_"),size_) ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("rect_"),rect_)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("point"),point)) << std::endl ;
std::tout << ::To_tstring(::INI_get(_T("test"),_T("size_"),size_)) << std::endl ;
}
}