当前,我为C-Library编写了一个C++包装器,该C-Library作为相机的驱动程序。相机可以设置属性,可以是float
,bool
或int
。每个酒店都有一个身份证,该证件是enum PropId
的成员。对于这些类型的,还有一个属性信息struct
,一个函数来获取和设置值:将类型作为枚举类型的C-API封装在C++中
GetPropertyAttribsI
GetPropertyAttribsB
GetPropertyAttribsF
PropAttribsI
PropAttribsF
PropAttribsB
SetPropertyValueI
SetPropertyValueF
SetPropertyValueB
我的问题是,现在我要编写代码:
- 检查是否要设置的属性值在范围内,否则将其设置为默认值。边界和默认值可以在
PropAttribs struct
中查找,可以使用相应的GetPropertyAttribs
函数进行初始化。 - 设置属性与相应
SetPropertyValue(I,B,F)
我可以看一下属性的类型,它是在enum (PROP_TYPE_INT, PROP_TYPE_FLOAT, PROP_TYPE_BOOL)
。
所以,我要的是一个功能:
checkAndSanitizeProperty(T& value, PropId property)
,检查一个给定的属性是否超出范围,否则将其设置为默认值。
框架将如下,但我不知道如何使它与模板参数非常通用,它可用于bool
和float
而无需复制。设置参数的功能与此非常相似,并且如果找到任何参数,应该有相同的解决方案。
void CameraHandle::checkAndSanitizeProperty(int& value, VRmPropId property, std::string name) {
VRmPropInfo propInfo;
VRM_CHECK(VRmUsbCamGetPropertyInfo(device, property, &propInfo));
if (VRM_PROP_TYPE_INT != propInfo.m_type) {
ROS_ERROR("Invalid type of property!");
}
VRmPropAttribsI attribs;
VRmUsbCamGetPropertyAttribsI(device, property, &attribs);
if (value < attribs.m_min || value > attribs.m_max) {
ROS_WARN("Invalid value for parameter %s, has to be in [%d,%d], but was: %d",
name.c_str(),
attribs.m_min,
attribs.m_max,
value);
ROS_WARN("Default will be used for %s: %d", name.c_str(), attribs.m_default);
value = attribs.m_default;
}
}
对我的神经有什么让我不得不重复许多代码,所以我寻找一个更干净的解决方案。我不主要使用C++,所以我对模板魔法或C++习惯用法没有太多的经验。
这看起来很酷。不幸的是,我认为它比简单地复制每种类型的函数的可读性和可维护性都差。 – reindeer
@reindeer如果您只有1或2个函数,那么编写手工生成的宏比使用上述宏更好。最后你会得到一个统一的商业逻辑功能,这很好。 – Yakk