vec::extension::visit
重要なファクターその3
visitorパターンを利用して vec へ対して操作を行っていきます。
例によって operator| で簡易接続。
まぁここら辺は殆ど『C++テンプレートテクニック』を真似ているだけなんですが…。
#include#include #include #include "vec/vec.hpp" #include "vec/extension/visit.hpp" #include "vec/type_traits/value.hpp" namespace kmt_ex{ namespace math{ namespace vec{ namespace extension{ /** ベクトル型を std::string に変換 */ struct to_string_impl{ typedef std::string result_type; template< int D, typename T > std::string operator ()(const vec & vec) const{ std::ostringstream oss; oss << "{ "; for( int i = 0 ; i < D ; i++ ){ oss << vec.value[i] << " "; } oss << "}"; return oss.str(); } }; static const to_string_impl to_string; } } } } // namespace kmt_ex{ namespace math{ namespace vec{ namespace extension{ namespace vec{ namespace sample{ namespace vec = kmt_ex::math::vec; typedef vec::vec<3, float> vec3; void visit_main(){ using kmt_ex::math::vec::extension::to_string; vec3 v; v.value[0] = 0.5f; v.value[1] = 1.5f; v.value[2] = 2.5f; std::cout << vec::extension::visit(v, to_string) << "\n"; std::cout << (v|to_string) << "\n"; // operator | での呼び出し } }; };
/** ベクトル型に対しての操作を行う 以下の条件をFが満たしていれば使用可能 1.関数か、関数オブジェクト(operator()が定義されているクラス) 2.関数オブジェクトの場合は、戻り値を定義しておく必要がある result_type か、templatestruct result{ type };の定義 */ template< typename T, typename F > typename detail::result_of ::type visit(T& obj, F func){ return func(obj); }; template< typename T, typename F > typename detail::result_of ::type visit(const T& obj, F func){ return func(obj); }; template< typename T, typename F > typename detail::result_of ::type operator |(T& obj, F func){ return visit(obj, func); }; template< typename T, typename F > typename detail::result_of ::type operator |(const T& obj, F func){ return visit(obj, func); };
自前で、result_of を実装してみたけどかなりやんちゃな事をしているので、
かなり胡散臭いです…。
あーboost 使いたいー。