我们应该如何使用枚举 class 进行索引(或者我们应该最好避免这种情况)?
How should we use an enum class for indexing (or should we better avoid this)?
假设我们有一个 enum
类型 foo
,我们想用它来索引静态大小的数组 arr
。
如果我们想为此使用 enum class
,我们可以这样尝试:
enum class foo
{
a,
b,
c,
count
};
std::array<T, static_cast<int>(foo::count)> arr;
但是,count
字段是一个 hack。能不能更优雅的获取foo
的字段数?
无论如何,真正糟糕的是我们还需要使用 static_cast
访问数组:arr[static_cast<int>(foo::a)]
.
当然我们可以编写自定义 "at" 函数(参见 https://www.fluentcpp.com/2019/01/15/indexing-data-structures-with-c-scoped-enums/) or provide an "enum_array" class (see ),但是这两种解决方案在某种程度上都很复杂,我们最好放弃并使用简单的 std::array<T, int>
代替。 ..
然而,阅读arr[foo::a]
而不是arr[0]
更直观,我们总是需要记住后者的索引0
的含义。
我们可以做得更好吗?
不,不是真的。
有很多提议可以静态反映枚举值。 None 还在 C++ 中。
我的意思是你可以这样做:
namespace foo {
enum value {
a,b,c,count
};
}
然后到 int 的转换是隐式的,您不会污染包含的命名空间。
solution here 开销非常接近于 0,并且允许您使用枚举(并且仅使用枚举)作为 []
.
的键
所以你得到:
enum_array<foo, T> arr;
和 arr
的行为如您所愿。
作为部分解决方案,您可以定义
constexpr std::underlying_type_t<foo> operator*(foo f) {
return static_cast<std::underlying_type_t<foo>>(f);
}
然后写
int bar(std::array<int, *foo::count>& arr) {
return arr[*foo::b];
}
假设我们有一个 enum
类型 foo
,我们想用它来索引静态大小的数组 arr
。
如果我们想为此使用 enum class
,我们可以这样尝试:
enum class foo
{
a,
b,
c,
count
};
std::array<T, static_cast<int>(foo::count)> arr;
但是,count
字段是一个 hack。能不能更优雅的获取foo
的字段数?
无论如何,真正糟糕的是我们还需要使用 static_cast
访问数组:arr[static_cast<int>(foo::a)]
.
当然我们可以编写自定义 "at" 函数(参见 https://www.fluentcpp.com/2019/01/15/indexing-data-structures-with-c-scoped-enums/) or provide an "enum_array" class (see ),但是这两种解决方案在某种程度上都很复杂,我们最好放弃并使用简单的 std::array<T, int>
代替。 ..
然而,阅读arr[foo::a]
而不是arr[0]
更直观,我们总是需要记住后者的索引0
的含义。
我们可以做得更好吗?
不,不是真的。
有很多提议可以静态反映枚举值。 None 还在 C++ 中。
我的意思是你可以这样做:
namespace foo {
enum value {
a,b,c,count
};
}
然后到 int 的转换是隐式的,您不会污染包含的命名空间。
solution here 开销非常接近于 0,并且允许您使用枚举(并且仅使用枚举)作为 []
.
所以你得到:
enum_array<foo, T> arr;
和 arr
的行为如您所愿。
作为部分解决方案,您可以定义
constexpr std::underlying_type_t<foo> operator*(foo f) {
return static_cast<std::underlying_type_t<foo>>(f);
}
然后写
int bar(std::array<int, *foo::count>& arr) {
return arr[*foo::b];
}