我正在读取enum二进制文件中的值,并想检查该值是否真的是enum值的一部分.我该怎么做?
#include <iostream>
enum Abc
{
A = 4,
B = 8,
C = 12
};
int main()
{
int v1 = 4;
Abc v2 = static_cast< Abc >( v1 );
switch ( v2 )
{
case A:
std::cout<<"A"<<std::endl;
break;
case B:
std::cout<<"B"<<std::endl;
break;
case C:
std::cout<<"C"<<std::endl;
break;
default :
std::cout<<"no match found"<<std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我是否必须使用switch操作员或有更好的方法吗?
编辑
我设置了枚举值,不幸的是我无法修改它们.更糟糕的是,它们不是连续的(它们的值为0,75,76,80,85,90,95,100等)
Leo*_*nid 24
enum如果值落在[A,B]范围内,则该值在C++中有效,该范围由下面的标准规则定义.因此,在这种情况下enum X { A = 1, B = 3 },值2被视为有效的枚举值.
考虑7.2/6的标准:
对于枚举,其中emin是最小的枚举数且emax是最大的,枚举的值是bmin到bmax范围内的基础类型的值,其中bmin和bmax分别是最小值和最小值的最小值.可以存储emin和emax的位字段.可以定义具有未由其任何枚举器定义的值的枚举.
在C++中没有回顾.一种方法是另外列出数组中的枚举值,并编写一个可以进行转换的包装器,并可能在失败时抛出异常.
有关更多详细信息,请参阅有关如何将int转换为枚举的类似问题.
And*_*rew 11
也许使用这样的枚举:
enum MyEnum
{
A,
B,
C
};
Run Code Online (Sandbox Code Playgroud)
并检查
if (v2 >= A && v2 <= C)
Run Code Online (Sandbox Code Playgroud)
如果未指定枚举常量的值,则值从零开始,并在列表中向下移动时增加1.例如,给定
enum MyEnumType { ALPHA, BETA, GAMMA };
ALPHA的值为0,BETA的值为1,GAMMA的值为2.
jan*_*anm 10
在C++ 11中,如果您准备将枚举值列为模板参数,则有更好的方法.您可以将此视为一件好事,允许您在不同的上下文中接受有效枚举值的子集; 在从外部源解析代码时通常很有用.
下面示例的一个可能有用的补充是围绕相对于IntType的基础类型EnumType的一些静态断言,以避免截断问题.留下来作为锻炼.
#include <stdio.h>
template<typename EnumType, EnumType... Values> class EnumCheck;
template<typename EnumType> class EnumCheck<EnumType>
{
public:
template<typename IntType>
static bool constexpr is_value(IntType) { return false; }
};
template<typename EnumType, EnumType V, EnumType... Next>
class EnumCheck<EnumType, V, Next...> : private EnumCheck<EnumType, Next...>
{
using super = EnumCheck<EnumType, Next...>;
public:
template<typename IntType>
static bool constexpr is_value(IntType v)
{
return v == static_cast<IntType>(V) || super::is_value(v);
}
};
enum class Test {
A = 1,
C = 3,
E = 5
};
using TestCheck = EnumCheck<Test, Test::A, Test::C, Test::E>;
void check_value(int v)
{
if (TestCheck::is_value(v))
printf("%d is OK\n", v);
else
printf("%d is not OK\n", v);
}
int main()
{
for (int i = 0; i < 10; ++i)
check_value(i);
}
Run Code Online (Sandbox Code Playgroud)
C ++托管扩展支持以下语法:
enum Abc
{
A = 4,
B = 8,
C = 12
};
Enum::IsDefined(Abc::typeid, 8);
Run Code Online (Sandbox Code Playgroud)
参考:MSDN“ C ++编程的托管扩展 ”
小智 5
有点死灵,但是......对 int 进行 RANGE 检查到第一个/最后一个枚举值(可以与 janm 的想法结合起来进行精确检查),C ++ 11:
标题:
namespace chkenum
{
template <class T, T begin, T end>
struct RangeCheck
{
private:
typedef typename std::underlying_type<T>::type val_t;
public:
static
typename std::enable_if<std::is_enum<T>::value, bool>::type
inrange(val_t value)
{
return value >= static_cast<val_t>(begin) && value <= static_cast<val_t>(end);
}
};
template<class T>
struct EnumCheck;
}
#define DECLARE_ENUM_CHECK(T,B,E) namespace chkenum {template<> struct EnumCheck<T> : public RangeCheck<T, B, E> {};}
template<class T>
inline
typename std::enable_if<std::is_enum<T>::value, bool>::type
testEnumRange(int val)
{
return chkenum::EnumCheck<T>::inrange(val);
}
Run Code Online (Sandbox Code Playgroud)
枚举声明:
enum MinMaxType
{
Max = 0x800, Min, Equal
};
DECLARE_ENUM_CHECK(MinMaxType, MinMaxType::Max, MinMaxType::Equal);
Run Code Online (Sandbox Code Playgroud)
用法:
bool r = testEnumRange<MinMaxType>(i);
Run Code Online (Sandbox Code Playgroud)
上面提出的主要区别是测试函数仅依赖于枚举类型本身。