C++11 范围内的枚举器(enum class
语法)不会转换为整数,因此它们不能直接用作数组索引。
以这种方式使用它们时,获得作用域优势的最佳方法是什么?
我提供了几个答案,但请添加更多想法!
最佳答案
解决方案 1:运算符重载。
这是我目前最喜欢的。重载一元 operator+
和 operator++
以分别显式转换为整数类型和枚举类型内的增量。
使用 enumeration_traits
模板,可以激活重载而不是复制样板代码。但样板只是几个单行代码。
库代码(模板,非模板替代方案见下文):
template< typename e >
struct enumeration_traits;
struct enumeration_trait_indexing {
static constexpr bool does_index = true;
};
template< typename e >
constexpr
typename std::enable_if< enumeration_traits< e >::does_index,
typename std::underlying_type< e >::type >::type
operator + ( e val )
{ return static_cast< typename std::underlying_type< e >::type >( val ); }
template< typename e >
typename std::enable_if< enumeration_traits< e >::does_index,
e & >::type
operator ++ ( e &val )
{ return val = static_cast< e >( + val + 1 ); }
用户代码:
enum class ducks { huey, dewey, louie, count };
template<> struct enumeration_traits< ducks >
: enumeration_trait_indexing {};
double duck_height[ + ducks::count ];
样板代码(如果不使用库,遵循enum
定义):
int operator + ( ducks val )
{ return static_cast< int >( val ); }
ducks &operator ++ ( ducks &val )
{ return val = static_cast< ducks >( + val + 1 ); }
解决方案 2:手动确定范围。
作用域枚举器语法也适用于非作用域(非 enum class
)枚举,它们会隐式转换为 int
。将枚举隐藏在类或命名空间中并使用 typedef
或 using
将其导入,使其成为伪作用域。
但如果多个枚举进入同一个命名空间,枚举器名称可能会发生冲突,因此您不妨使用一个类(或多个命名空间)。
struct ducks_enum {
enum ducks { huey, dewey, louie, count };
};
typedef ducks_enum::ducks ducks;
double duck_height[ ducks::count ]; // C++11
double duck_weight[ ducks_enum::count ]; // C++03
这有一些好处。 它适用于 C++03,但仅适用于语法 ducks_enum::count
。枚举器在结构内部是无作用域的,它可以用作任何频繁使用枚举器的类的基础。
关于c++ - 具有范围枚举的数组索引(转换为整数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12927951/