如何按功能模板参数化函数?

时间:2015-10-28 13:10:41

标签: c++ templates

在为结构实现字节顺序转换功能时,我发现实现违反了DRY原则 这是代码段以显示我的意思:

inline void FromHostByteorderToNetwork(ServerStatus& ss) {
  ss.field0 = qToBigEndian<__int32>(ss.field0);
  ss.field1 = qToBigEndian<__int16>(ss.field1);
//... 20+ more fields assigned in the same way

inline void FromNetworkByteorderToHost(ServerStatus& ss) {
  ss.field0 = qFromBigEndian<__int32>(ss.field0);
  ss.field1 = qFromBigEndian<__int16>(ss.field1);
//... 20+ more fields assigned in the same way

我想要的:一个例程,我可以传递模板函数的名称(qToBigEndian / qFromBigEndian),实现如下:

template <typename ByteConversionFunctionT>
inline void changeByteOrder(ServerStatus& ss) {
      ss.field0 = ByteConversionFunctionT<__int32>(ss.field0);
      ss.field1 = ByteConversionFunctionT<__int16>(ss.field1);

重要信息:
另外,请注意changeByteOrder中的ByteConversionFunctionT是用不同的类型实例化的:如__int32 / __ int16

在Qt标题中的

qFrom / To是一个模板:

template <typename T> inline T qFromBigEndian(T source)

你能建议如何做到这一点,或者为了避免额外的复杂性而遵守KISS和重复代码?

1 个答案:

答案 0 :(得分:6)

一种选择是编写类模板包装器:

template <class T>
struct FromBigEndian
{
  static T call(T source) { return qFromBigEndian(source); }
};

template <class T>
struct ToBigEndian
{
  static T call(T source) { return qToBigEndian(source); }
};

template <template <class> class ByteConvertor>
void changeByteOrder(ServerStatus &ss)
{
  ss.field0 = ByteConvertor<__int32>::call(ss.field0);
  ss.field1 = ByteConvertor<__int16>::call(ss1.field1);
}