设为首页 加入收藏

TOP

结构体自动化转为char数组(四)
2014-04-06 17:36:02 来源: 作者: 【 】 浏览:337
Tags:结构 自动化 转为 char 数组

 

  这种自动化的转换不仅仅大大降低了转换的复杂度还解决了手工拷贝的时候容易出错的问题,程序自动化的拷贝保证了拷贝的正确性。目前我还没看到有类似的转换类或者函数能够自动地很方便地将复杂结构体转换为char数组,想想自己实现一个也不是难事,其实要实现自动转换最关键的是要获取结构体的元信息,有了元信息我们就能对结构体中的每个字段进行转换了。在c#中可以通过反射很方便的获取结构体的元信息,而c++中没有反射,就要想其它办法来获取元信息了。而且这个获取元信息的方法还要非常简单,几乎不增加额外的负担。这里我是通过tuple来获取原信息,要求每个结构体要定义一个Get方法来返回其字段的基本信息,比如:

  struct A

  {

  int x;

  double y;

  auto Get()->decltype(std::make_tuple(x,y))

  {

  return std::make_tuple(x,y);

  }

  };

  这个Get方法非常简单,只要将字段放到tuple中返回出去就行了,几乎没有增加额外的负担,这个看似简单函数却有着巨大的作用,只要有这个Get函数我就可以获取结构体的基本元信息了,有了这个以后,所有的转换都可以实现自动化了。还是来看看具体是如何实现自动化的转换吧:

  #include

  #include

  #include

  namespace Cosmos

  {

  namespace Detail

  {

  struct Functor

  {

  Functor(char* buf, int len) :m_buf(buf), m_bufLen(len)

  {

  }

  template

  typename std::enable_if::value>::type operator()(T t)

  {

  FillForward(t);

  }

  template

  typename std::enable_if< xml:namespace prefix = std />::value>::type operator()(T& t)

  {

  FillForward(t);

  }

  private:

  template

  void FillForward(T&& t)

  {

  if (std::is_same::value || std::is_same::value)

  m_latestInt = t;

  FillIn(std::forward(t), m_buf + m_curPos);

  m_curPos += sizeof(T);

  }

  template

  typename std::enable_if::value>::type FillIn(T t, char* p)

  {

  *((T*) p) = t;

  }

  template

  typename std::enable_if::value>::type FillIn(T t, char* p)

  {

  if(std::is_same::value)

  sprintf(p, "%.15f", t);

  else

  sprintf(p, "%f", t);

  }

  template

  typename std::enable_if::value&&std::is_class::type>::value>::type FillIn(T t,

  char* p)

  {

  Fill(t, p, [this, &t](int i, char* p, int size){Put(p + i*size, size, t[i]); });

  }

  template

  typename std::enable_if::value&&std::is_arithmetic::type>::value>::type FillIn(T

  t, char* p)

  {

  Fill(t, p, [this, &t](int i, char* p, int size){FillIn(t[i], p + i*size); });

  }

  template

  void Fill(T t, char* p, F&& f)

  {

  int count = m_latestInt.AnyCast();

  using U = typename std::remove_pointer::type;

  for (int i = 0; i < count; i++)

  {

  f(i, p, sizeof(U));

  }

  }

  template

  typename std::enable_if::value&&std::is_void::type>::value>::type FillIn(T t,

  char* p)

  {

  int count = m_latestInt.AnyCast();

  int* temp = (int*) t;

  for (int i = 0; i < count; i++)

  {

  FillIn(temp[i], p + i*sizeof(int));

  }

  }

  template

  typename std::enable_if::value>::type FillIn(T& t, char* p)

  {

  strcpy(p, t.c_str());

  }

  template

  typename std::enable_if::value&&!std::is_same::value>::type FillIn(T& t, char* p)

  {

  Put(p, sizeof(T), t);

  }

  char* m_buf;

  int m_bufLen;

  int m_curPos = 0;

  Any m_latestInt = 0;

  };

  template

  void for_each_impl(Func&& f, Last&& last)

  {

  f(last);

  }

  template

  void for_each_impl(Func&& f, First&& first, Rest&&...rest)

  {

  f(first);

  for_each_impl(std::forward(f), rest...);

  }

  template

  void for_each_helper(Func&& f, IndexTuple, std::tuple&& tup)

  {

  for_each_impl(std::forward(f), std::forward(std::get(tup))...);

  }

  }

  template

  void tp_for_each(Func&& f, std::tuple& tup)

  {

  using namespace details;

  for_each_helper(forward(f), typename make_indexes::type(), std::tuple(tup));

  }

  template

  void tp_for_each(Func&& f, std::tuple&& tup)

  {

  using namespace details;

  for_each_helper(forward(f), typename make_indexes::type(), forward>(tup));

  }

  template

  void Put(char* p, int len, T&& t)

  {

  using namespace Detail;

  tp_for_each(Functor(p, len), t.Get());

  }

  }

  View Code

  代码中用到了Any,这个Any就是我前面的博文中实现的Any,想查看可以点这里。

        

首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++非类型模板参数 下一篇关于构造函数c++

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言指针从入门到基 (2025-12-26 05:21:36)
·【C语言指针初阶】C (2025-12-26 05:21:33)
·C语言指针的定义和使 (2025-12-26 05:21:31)
·在 Redis 中如何查看 (2025-12-26 03:19:03)
·Redis在实际应用中, (2025-12-26 03:19:01)