读书人

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

发布时间: 2013-03-25 15:43:04 作者: rapoo

有难度!请教如何用模版解决我的问题.
标题为了吸引眼球,抱歉。
自认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());
}



读书人网 >C++

热点推荐