背景:我们有一个带有专用整数类型的嵌入式处理器。我们在C ++中对这些类型进行了仿真,以允许在Visual Studio或gcc下构建代码,并且计算产生的值与嵌入式处理器上的值相同。
以下代码可以很好地编译嵌入式处理器(其中int_t
是我们的自定义整数类型):
enum foo { VAL_0, VAL_1, VAL_2 };
int_t my_val = VAL_1;
foo foo_val = (foo)val;
嵌入式处理器的编译器以与int相同的方式将int_t视为普通整数类型,因此将其转换为枚举是合法的,就像将int转换为枚举一样。
int_t
的C ++仿真是一个类,它重载各种运算符,使它们具有与嵌入类型相同的行为。
我们希望允许此代码在任何任意枚举的仿真下编译。显然,我们可以向类中的任何特定枚举添加一个强制转换运算符,但是我们提供了一个通用库,我们希望允许开发人员为它们可能开发或使用的任意枚举执行此操作。
有没有办法在C ++中实现这种行为,以便在这种情况下它的行为与标准的int类型完全相同?
答案 0 :(得分:3)
使用C ++ 11的std::is_enum
和一些限制构造函数的sfinae:
template<typename E>
int_t::int_t(E e, typename std::enable_if<std::is_enum<E>::value>::type* = nullptr)
或者在C ++ 14中略显整洁:
template<typename E>
int_t::int_t(E e, std::enable_if_t<std::is_enum<E>::value>* = nullptr)
在C ++ 17中最整洁:
template<typename E>
int_t::int_t(E e, std::enable_if_t<std::is_enum_v<E>>* = nullptr)
我最初是在错误的方向上做的。要允许将转换为枚举,只转换为枚举,您将以类似的方式编写转换运算符:
template<typename E, std::enable_if_t<std::is_enum<E>::value>* = nullptr>
operator E() { return E{val}; }
答案 1 :(得分:3)
也许你可以提供一个试图转换整数表示的模板转换操作符:
class int_t{
public:
int_t(int X) {}
template<typename T>
operator T(){ return static_cast<T>(42); }
};
enum foo { VAL_0, VAL_1, VAL_2 };
int main()
{
int_t my_val = VAL_1;
foo foo_val = (foo)my_val;
}
如果整数值int_t
无法static_cast
到目标类型,则无法实例化。
如果您希望int_t
尽可能密切关注int
类型,我可能更愿意将此限制仅仅限制为enum
s。
答案 2 :(得分:-1)
如我的评论所示,一个非常简单的解决方案是使用像E(int(my_val))
这样的两步转换。在嵌入式目标上,int()
转换是多余的,可能没有任何内容,或只是转换为另一种整数类型,E()
转换也是如此。
在模拟中,int()
转换实际上会根据需要调用用户定义的转换运算符。