背景:我们有一个具有专门整数类型的嵌入式处理器。我们在C++中对这些类型进行了模拟,以允许在Visual或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转换为enum一样。
C++模拟int_t是一个类,它重载各种操作符,使它们具有与嵌入式类型相同的行为。
我们希望允许此代码也在仿真下编译,以用于任何任意枚举。显然,我们可以在类中的任何特定枚举中添加一个cast操作符,但是我们提供了一个通用库,我们希望允许开发人员对他们可能开发或使用的任意枚举执行此操作。
是否有任何方法在C++中实现此行为,以便在这种情况下它的行为与标准int类型完全等价?
发布于 2017-01-26 12:38:24
使用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}; }发布于 2017-01-26 12:41:08
也许您可以提供一个尝试转换整数表示的模板强制转换操作符:
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上。
发布于 2017-01-26 15:02:36
正如我在评论中指出的,一个非常简单的解决方案是使用像E(int(my_val))这样的两步转换。在嵌入的目标上,int()转换是多余的,可能什么也不做,或者只是转换到另一个整数类型,就像E()转换一样。
在仿真中,int()转换实际上按需要调用用户定义的转换操作符。
https://stackoverflow.com/questions/41873538
复制相似问题