首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

有难度!请问怎么用模版解决小弟我的有关问题

2013-03-25 
有难度!请教如何用模版解决我的问题.标题为了吸引眼球,抱歉。自认c++水平还可以,但是以下问题不知道如何解

有难度!请教如何用模版解决我的问题.
标题为了吸引眼球,抱歉。
自认c++水平还可以,但是以下问题不知道如何解决。
1. 首先有如下的一个struct
    typedef struct __field_holder{
        uint8   type ;   //记录union中的具体类型
        union{
            int8        i8  ;
            uint8       u8  ;
            int16       i16 ;
            uint16      u16 ;
            int32       i32 ;
            uint32      u32 ;
            int64       i64 ;
            uint64      u64 ;
            bool        bv  ;
            char *      str ;
            float       f32 ;
            double      f64 ;
            void *      raw ;
    time_tt32 ;
            int64t64 ;
            uint64      val ;       //用来清除数值的
        }data ;    
    } field_holder;
这个struct的目的一目了然,通过union的结构存放一个任意类型的变量.

2. 我现在要写一系列的函数,对这个struct进行大小比较,例如==,!=,<,>...
比如“==”的实现如下
bool equal_to(const __field_holder *lholder, const __field_holder *rholder) const
{
bool ret = false;

switch(lfield->type())
{
case ss::SSTYPE_INT8 : 
ret = (lholder->data.i8 == rholder->data.i8);
break ;
case ss::SSTYPE_INT16 : 
ret = (lholder->data.i16 == rholder->data.i16);
break ;
case ss::SSTYPE_INT32 : 
ret = (lholder->data.i32 == rholder->data.i32) ;
break ;
case ss::SSTYPE_INT64 : 
ret = (lholder->data.i64 == rholder->data.i64) ;
break ;
case ss::SSTYPE_FLOAT : 
ret = (lholder->data.f32 == rholder->data.f32) ;
break ;
case ss::SSTYPE_DOUBLE : 
ret = (lholder->data.f64 == rholder->data.f64) ;
break ;
case ss::SSTYPE_STRING :
ret = (string(lholder->data.str) == string(rholder->data.str)) ;
break ;
case ss::SSTYPE_T32 :
ret = (lholder->data.t32 == rholder->data.t32) ;


break ;
case ss::SSTYPE_T64 :
ret = (lholder->data.t64 == rholder->data.t64) ;
break ;
case ss::SSTYPE_BIT64 :
ret = (lholder->data.u64 == rholder->data.u64) ;
break ;
default:
break ;
}
return ret;
}

如果我要实现"!=",我只要把上面函数里的"==”改成"!="就好了,其它比较也类似。
所以,我的问题来了。
我感觉应该是不需要写重复代码,用个简单的技巧,就可以把"操作符"替换的。
我一开始想到了用std::equal_to,这类function object来解决,把"操作符"通过参数的方式传递到函数里,但是我发现,这是不可以的,因为里面所有的==左右操作数类型是不一样的,没办法实例化模版。
请教各位高手,有什么办法,让我不需要写重复代码。
谢谢 模版 function?object
[解决办法]
参考libcstl对通用数据类型的处理,libcstl(http://code.google.com/p/libcstl/)是使用标准C编写的一个通用的数据结构和常用的算法库,它模仿SGI STL的接口和实现。
[解决办法]
template <class T>
struct __field_holder
{
T data;

bool operator==(const __field_holder<T> &other)
{
return data == other.data;
};

bool operator!=(const __field_holder<T> &other)
{
return data != other.data;
};
};

//!=的特化
template <>
bool __field_holder<char *>::operator!=(const __field_holder<char *> &other)
{
//char *类型的特殊处理
};
[解决办法]
自定义functor就好啦


//are you sure this function should be inline?
//1 : don't optimize
//2 : don't optimize yet
bool equal_to(const __field_holder *lholder, const __field_holder *rholder) const
{
bool ret = false;

switch(lfield->type())
{
case ss::SSTYPE_INT8 : 
ret = (lholder->data.i8 == rholder->data.i8);
break ;
case ss::SSTYPE_INT16 : 
ret = (lholder->data.i16 == rholder->data.i16);
break ;
//......
}


we could change it to

//are you sure this function should be inline?
//1 : don't optimize
//2 : don't optimize yet
template<typename BiFunc>
bool compare_to_impl(const __field_holder *lholder, const __field_holder *rholder, BiFunc func) const
{
bool ret = false;

switch(lfield->type())
{
case ss::SSTYPE_INT8 : 
ret = (func(lholder->data.i8, rholder->data.i8));
break ;
case ss::SSTYPE_INT16 : 
ret = (func(lholder->data.i16, rholder->data.i16));
break ;
//......
}

class holder_equal_to
{
  public:
  template<typename T, typename U>
  bool operator()(T a, T b) const
  {
    return a == b;
  }

  template<>
  bool operator()(char *a, char *b) const{//....}
};

bool equal_to(const __field_holder *lholder, const __field_holder *rholder, BiFunc func)


{
  return compare_to_impl(lholder, rholder, equal_to());
}



热点排行