gpt4 book ai didi

c++ - 在 C++ 中用枚举类型包装 C-API

转载 作者:太空狗 更新时间:2023-10-29 21:39:42 25 4
gpt4 key购买 nike

目前,我为 C 库编写了一个 C++ 包装器,用作相机的驱动程序。相机可以设置为 floatboolint 的属性。每个属性都有一个 ID,它是 enum PropId 的成员。对于这些类型中的每一个,都有一个属性信息struct,一个获取和设置值的函数:

GetPropertyAttribsI
GetPropertyAttribsB
GetPropertyAttribsF
PropAttribsI
PropAttribsF
PropAttribsB
SetPropertyValueI
SetPropertyValueF
SetPropertyValueB

我现在的问题是我想编写代码:

  1. 检查要设置的属性值是否在范围内,否则将其设置为默认值。可以在 PropAttribs 结构 中查找边界和默认值,可以使用相应的 GetPropertyAttribs 函数对其进行初始化。
  2. 使用相应的 SetPropertyValue(I,B,F)
  3. 设置属性

我可以查找属性的类型,它在 enum (PROP_TYPE_INT, PROP_TYPE_FLOAT, PROP_TYPE_BOOL) 中。

所以我想要的是一个函数:

checkAndSanitizeProperty(T& value, PropId property)

检查给定属性是否在边界内,否则将其设置为默认值。

框架如下,但我不知道如何使用模板参数使它变得如此通用,以至于无需复制即可用于 boolfloat。设置参数的函数和那个很像,如果找到应该有相同的解决方法。

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++ 习语没有太多经验。

最佳答案

宏黑客。

#define CONCAT2( A, B ) A##B
#define CONCAT(A,B) CONCAT2(A,B)

#define MAP_STRUCT( X ) \
template<class T> struct X; \
template<class T> using CONCAT(X,_t) = typename X<T>::type; \
template<> struct X<int> { \
using type= CONCAT(X, I); \
}; \
template<> struct X<float> { \
using type= CONCAT(X, F); \
}; \
template<> struct X<bool> { \
using type= CONCAT(X, B); \
};

采用基本结构名称,如 VRmPropAttribs并使VRmPropAttribs_t<int>VRmPropAttribsI .

#define CALL(X) CONCAT( call_, X )
#define MAP_FUNC_CALL(X) \
template<class T> \
struct CALL( X ); \
template<> struct CALL(X)<int> { \
template<class...Args> \
auto operator()(Args&&...args)const \
-> decltype( CONCAT(X,I)(std::declval<Args>()...) ) { \
return CONCAT(X,I)(std::forward<Args>(args)...); \
} \
}; \

B 和 F 等

 #define MAP_FUNC(X) \
MAP_FUNC_CALL(X) \
template<class T, class...Args> \
auto X(Args&&...args) \
-> typename std::result_of< CALL(X)(Args...) > \
{ return CALL(X)<T>{}(std::forward<Args>(args)...); }

它定义了一个名为 X 的函数模板那,当通过int , 来电 XI具有相同的论点。

现在,这不会处理您的 %d格式化字符串等,但您可以执行以下操作:

VRmPropAttribs 属性; VRmUsbCamGetPropertyAttribs(设备、属性、&attribs);使用上述宏后。一旦可以执行上述操作,就可以替换 intT并使您的方法成为模板方法。

您还需要更好版本的 VRM_PROP_TYPE_INT :

template<class T> struct vrm_prop_type{};
template<> struct vrm_prop_type<int>:
std::integral_constant<int, VRM_PROP_TYPE_INT>
{};

etc 让你做:

vrm_prop_type<T>{} != propInfo.m_type

检查。

关于c++ - 在 C++ 中用枚举类型包装 C-API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32273671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com