在c++函数中传递原始数据类型的最佳实践
Best practice for passing primitive data type in C++ function
我正在为avr芯片编写一个函数,将字节流反序列化为基本类型。我希望以尽可能通用的方式来实现它,并且想知道确定要反序列化的类型的最佳实践是什么。到目前为止,我的想法包括:
选择:
// 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似乎是这里明显的赢家,假设您不关心字节排序或使用联合的其他潜在警告(似乎不会给您提供此工作的上下文)。
另一件要考虑的事情是在反序列化时使用一些反馈机制来推进字节流指针/索引。也许你可以试试
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指定模板实参。
另一个选项是将结果作为"out"参数返回。在这种情况下,您不需要在模板实例化期间指定类型。像这样:
template <typename TYPE>
void deserialize(uint8_t *in, TYPE& out) {
union {
TYPE real;
uint8_t base[sizeof(TYPE)];
} u;
for (unsigned int i = 0; i < sizeof(TYPE); i++) {
u.base[i] = in[i];
}
out = u.real;
return;
}
// Call:
double value = 0;
deserialize(in, value);
警告:
通常不推荐使用c++进行AVR,原因有很多,而且有些事情完全无法工作——所以在投入大量时间进行任何特定的路径之前,请仔细在目标芯片上测试您的代码。
但这并不意味着你必须放弃任何重要的功能。只需调整您的代码以适应可用的语言特性。
在我看来选择B是最好的。它增加了更多的可读性和易于使用。此外,TYPE也可以是更大的类/结构吗?因为您是按deserialize()
方法的值返回的!
你应该选择A,因为:
- 它引入了最少的复杂性。
- 兼容C和c++。
- 如果不支持该类型,则提供直接的行为。
请注意,如果您想要选择B的语法,总是可以在以后的日期在选择A的代码之上实现它(通过为不同类型提供专门化)。
相关文章:
- 防止主数据类型C++的隐式转换
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 在c代码之间共享数据的最佳方式
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何计算数据类型的范围,例如int
- C++中数据类型修饰符的顺序
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 特定数据类型的模板类
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- 什么是在C 中存储结果INT*的最佳数据类型
- 返回一组数据类型之一的最佳模式
- 使用无符号数据类型强制执行非负值和/或有效值是否是一种最佳做法
- c++中派生类携带不同数据类型的最佳方式
- 存储大量不同类型数据的最佳方式
- 在C/C++中存储21.6.7.1等值的最佳数据类型
- 传递多种数据类型的最佳方法
- 在c++函数中传递原始数据类型的最佳实践