Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parametrize function by function template?

Tags:

c++

templates

While implementing byte order conversion function for a structure, I found out that implementation violates DRY principle.
Here is the code snippet to show what I mean:

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

What I want: one routine, where I can pass name of template function (qToBigEndian/qFromBigEndian), with implementation like:

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

Important information:
Also, notice that ByteConversionFunctionT inside changeByteOrder is instantiated with different type: like __int32/__int16

in Qt headers qFrom/To is a template:

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

Can you suggest the way to do it, or maybe to obey KISS and duplicate code in order to avoid additional complexity?

like image 860
spin_eight Avatar asked Oct 28 '15 13:10

spin_eight


1 Answers

One option would be to write a class template wrapper:

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);
}
like image 162
Angew is no longer proud of SO Avatar answered Sep 28 '22 06:09

Angew is no longer proud of SO