c++ - 在 C++ 函数中传递原始数据类型的最佳实践

标签 c++ templates serialization avr

我正在为 avr 芯片编写一个函数,以将字节流反序列化为原始类型。我想以尽可能通用的方式进行操作,并且想知道确定要反序列化的类型的最佳做法是什么。到目前为止,我的想法包括:

选项A:

// Just write a function for each type
double deserialize_double(uint8_t *in) { }

选项 B:

// Use a template, and pass the type in when calling
// Function:
template <typename TYPE>
TYPE deserialize(uint8_t *in) {
  union {
    TYPE real;
    uint8_t base[sizeof(TYPE)];
  } u;

  for (unsigned int i = 0; i < sizeof(TYPE); i++) {
    u.base[i] = in[i];
  }
  return u.real;
}

// Call:
double value = deserialize<double>(in);

选项C:

// Similar to B, but you pass in the type as a parameter
// Function:
TYPE deserialize(uint8_t *in, TYPE);

// Call:
double value = deserialize(in, double);

选项D:

// Use a templated class. My main issue with this is I was hoping 
// to re-use the same object for deserializing multiple types.
template <typename TYPE>
class Serializer {
  public void serialize(uint8_t *out, TYPE value) { /* code */ }
  public TYPE deserialize(uint8_t *int) { /* code */ }
};

关于执行此操作的最佳方法有什么想法吗?也许我忽略了一种更简单的方法。

最佳答案

对于初学者来说,C 和 D 是无效的选项,因为类型不是有效的函数参数;不妨现在就将它们排除在外。

选项 B 似乎是这里明显的赢家,假设您不关心字节顺序或其他使用 union 的潜在警告(看起来您不会被告知这项工作的上下文)。

需要考虑的另一件事是在反序列化时使用一些反馈机制来推进字节流指针/索引。也许你可以尝试类似的东西

template <typename TYPE>
int deserialize(uint8_t *in, TYPE& value) {
    union {
        TYPE real;
        uint8_t base[sizeof(TYPE)];
    } u;

    for (unsigned int i = 0; i < sizeof(TYPE); i++) {
        u.base[i] = in[i];
    }
    value = u.real;
    return sizeof(TYPE);
}

// Call:
double foo, bar;
int baz;
in += deserialize(in, foo);   // Implicit double deserialize
in += deserialize(in, bar);   // Implicit double deserialize
in += deserialize(in, baz);   // Implicit int deserialize

这还有一个额外的好处(正如我所看到的@Asha 已经打败了我!)允许您利用 C++ 模板的类型推断系统;由于第二个参数在调用位置具有已知类型,因此无需为 TYPE 显式指定模板参数。

关于c++ - 在 C++ 函数中传递原始数据类型的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5609915/

相关文章:

c++ - 如何更改 C++'11 中指针的所有权?

C++ 循环重复代码

c++ - 处理运行时类型未知的模板

c++ - boost::dynamic_bitset 如何存储位

c# - 序列化 c# 使用 switch 序列化自述文件

c++ - std::string 在传递给库时会损坏/更改结构

c++ - 尝试使用 header 从 C++ 访问 matlab

c++ - 模板结构中的重载运算符

c++ - 模板定义如何与模板声明匹配?

java - 在 Java/Android 中维护一个可序列化的类