我正在为 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/