关于trait跟policy的互操作
关于trait和policy的互操作
近日写模板的时候遇到一个问题,与trait和policy之间的互操作有关,下面是简化后的代码:
在ResultSet::GetResult中需要给Data赋值,其值与不同的policy和不同的trait都有关,在Policy::GetData中需要根据不同的trait返回不同的内容。我只想到了在Policy::GetData内部使用typeid分辨不同的trait,由于有很多trait,造成每个policy都有一大串typeid,这写法太丑陋了,使用运行时RTTI也有点不爽,请问各位有否代码更优雅的意见?
------解决方案--------------------
推荐一下,值得研究一把~
------解决方案--------------------
近日写模板的时候遇到一个问题,与trait和policy之间的互操作有关,下面是简化后的代码:
- C/C++ code
template < typename T > class TraitSet; template<> class TraitSet< int > { public: typedef int TypeT; }; template<> class TraitSet< long > { public: typedef long TypeT; }; ................. //有很多trait template< typename T > class DefaultAction { public : ............ static T GetData( void ) { if( typeid( T ) == typeid( int ) ) { return 10; } if( typeid( T ) == typeid( long ) ) { return 20; } ..................... //有很多个typeid return T( ); } ............... }; ........................ //有一些policy,每个policy都有GetData template< typename T, typename Policy = DefaultAction< T >, template < typename > class Trait = TraitSet > class ResultSet { public : .............. static T GetResult( void ) { .............. typename Trait<T>::TypeT Data = Policy::GetData( ); ............... return Data; } ............ };
在ResultSet::GetResult中需要给Data赋值,其值与不同的policy和不同的trait都有关,在Policy::GetData中需要根据不同的trait返回不同的内容。我只想到了在Policy::GetData内部使用typeid分辨不同的trait,由于有很多trait,造成每个policy都有一大串typeid,这写法太丑陋了,使用运行时RTTI也有点不爽,请问各位有否代码更优雅的意见?
------解决方案--------------------
推荐一下,值得研究一把~
------解决方案--------------------
- C/C++ code
template<> class TraitSet< int > { public: typedef int TypeT; enum { res = 10 }; }; template<> class TraitSet< long > { public: typedef long TypeT; enum { res = 2 }; }; template< typename T,template < typename > class Trait = TraitSet > class DefaultAction { public : typedef Traits<T> traits;//把这个代入到ResultSet ............ static T GetData( void ) { return traits::res; } ............... };
------解决方案--------------------
可以对 policy 也特化吧,例如这样。
- C/C++ code
template <typename T> struct TraitSet; template <> struct TraitSet <int > { typedef int TypeT; }; template <> struct TraitSet <long> { typedef long TypeT; }; template <typename T> struct DefaultAction { static T GetData () { return T(); } }; template <> struct DefaultAction <int > { static int GetData () { return 10; } }; template <> struct DefaultAction <long> { static int GetData () { return 20; } }; // same thing for OtherAction.
------解决方案--------------------
不清楚楼主的具体需求
用映射应该是比较好的方案吧. 如楼上,,
更通用地可以考虑 Type 到 类类型静态对象的映射.
个人比较看好表驱动.
------解决方案--------------------
>这写法太丑陋了,使用运行时RTTI也有点不爽
杀掉RTTI,在编译器间作选择的方法
std::is_same<T1, T2>::value //(bool value)
如果你的编译器不支援std::is_same
- C/C++ code
template<typename T1, typename T2> class is_same { public: enum {value = 0}; } template<typename T> class is_same<T, T> { public: enum {value = 1}; };
------解决方案--------------------
lz 忘了可以特化 类成员函数么
- C/C++ code
template < typename T > class TraitSet; template<> class TraitSet< int > { public: typedef int TypeT; }; template<> class TraitSet< long > { public: typedef long TypeT; }; template< typename T > class DefaultAction { public : static T GetData( void ); }; template<> int DefaultAction<int>::GetData() { return 10; } template<> long DefaultAction<long>::GetData() { return 20; } int main() { printf( "%d\n" , DefaultAction<int>::GetData() ); printf( "%d\n" , DefaultAction<long>::GetData() ); return 0; }