c++ - 在 C++ 中将变量参数列表序列化为字节数组的最佳方法?

标签 c++ vector arrays variadic-functions

我有一个 C 实现,其中将参数的变量列表序列化为字节数组。 这样我就可以将一定数量的变量保存到一个文件中。

C 语言代码如下所示:

static uint8_t byte_array[1024];

/* In this example, we assume that fmt contains only 'c', 'i', or 'f'
   We also assume that an argument is available for each char in fmt.
*/

uint8_t * serialize_args(const char *fmt, ...) {
  char *ptr = fmt;
  uint32_t idx = 0;
  va_list args;
  va_start(args, fmt);

  while(*ptr != NULL) {
    char p = *ptr++;
    char c;
    int i;
    float f;

    switch(p) {
      case 'c':  /* serialize char */
        c = va_arg(args, int32_t);
        byte_array[idx++] = (uint8_t) c;
        break;
      case 'i':  /* serialize int */
        i = va_arg(args, int32_t);
        memcpy(&byte_array[idx], &i, sizeof i);
        idx += sizeof i;
        break;
      case 'f':  /* serialize float */
        f = (float)va_arg(args, double);
        memcpy(&byte_array[idx], &f, sizeof f);
        idx += sizeof f;
        break;
    }
  }    
  va_end(args, fmt);

  byte_array[idx++] = 0;
  return byte_array;
}

现在假设我想将其翻译为 C++。什么容器最适合? 一个 vector ?然后我会看起来像这样:

vector<uint8_t> serialize_args(const char *fmt, ...) {
  char *ptr = fmt;

  vector<uint8_t> byte_array;

  va_list args;
  va_start(args, fmt);

  while(*ptr != NULL) {
    char p = *ptr++;
    char c;
    int i;
    float f;

    switch(p) {
      case 'c':  // serialize char
        c = (char)va_arg(args, int32_t);
        byte_array.push_back(c);  // do I need a cast ?
        break;
      case 'i':  // serialize int
        i = va_arg(args, int32_t);
        // here how do I memcpy to a vector ?
        break;
      case 'f':  // serialize float
        f = (float)va_arg(args, double);
        // here how do I memcpy to a vector ?
        break;
    }
  }    

  va_end(args, fmt);

  return byte_array;
}

有什么建议吗?

最佳答案

使用指向字符类型的指针对任何类型进行别名是合法的,因此您可以执行以下操作(以及 int 的示例):

for (unsigned char* p = &i; p != &i+sizeof(int); ++p)
    byte_array.push_back(*p);

或者,也许更惯用的是:

std::copy(&i, &i + sizeof(int), std::back_inserter(byte_array));

您还可以使用memcpy,但需要事先使用 vector 的resize方法为sizeof(int)字节腾出空间。

在 C++11 中,您可以完全摆脱可变参数并使用可变参数模板函数。

关于c++ - 在 C++ 中将变量参数列表序列化为字节数组的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19514601/

相关文章:

javascript - 我想循环遍历数组并修改属性

c++ - 使一个类可用于其他程序

c++ - 如何创建自定义字节级数据类型?

c++ - 在 map 中使用字符串 vector

C++ std::vector<>::iterator 不是指针,为什么?

javascript - 通过展开运算符进行数组解构

c++ - "<"是否满足严格的弱排序意味着不需要 "=="定义?

c++ - Codeblocks graphics.h 不工作

performance - 有人可以澄清摊销常数时间(加倍数组向量)吗?

C 编程 - 反转字符串