std::get<0>(...) 和枚举索引
std::get<0>(...) and enum index
为了使代码更具可读性,我用tuple
做了以下操作:
std::tuple<uint32_t, uint32_t, uint32_t> key;
enum tpl {
arg1 = 0, arg2 = 1, arg3 = 2
};
现在我可以写:
auto _arg1 = std::get<tpl::arg1>(key);
我现在遇到一个问题。如果我写:
auto arg1 = std::get<tpl::arg1>(key);
变量arg1
已经是枚举。因此,我想切换到:
enum class tpl: int {
arg1 = 0, arg2 = 1, arg3 = 2
};
但是这里有些不对劲。编译器说:
错误 C2672:"std::get":未找到匹配的重载函数
这个索引在std::get
是什么类型,可以在枚举类的定义中命名吗?
我试过了
const constexpr
const int
....
作用域枚举 ( enum class
) 没有隐式转换为任何类型的整数。由于std::get
需要整型模板参数,因此必须进行此类转换。
但它不能,因此没有重载与提供的模板参数匹配。
您可以使用在 C++11 之前采用的"作用域枚举"黑客:
struct tpl {
enum : int {
arg1 = 0, arg2 = 1, arg3 = 2
};
};
这使得标识符的作用域,但保留隐式转换。引入了 C++11 作用域枚举,因为通常隐式转换不是所需的功能,但在这种情况下,我敢说它是。
问题是作用域枚举不会隐式转换为其基础类型。您可以通过以下方式手动执行此操作
std::get<static_cast<std::underlying_type_t<tpl>>(tpl::arg1)>(key);
但是,由于您的尝试是提高可读性,因此这不是一个很好的解决方案。相反,请考虑此选项:
namespace tpl {
enum { arg1 = 0, arg2 = 1, arg3 = 2 };
}
std::get<tpl::arg1>(key);
它不具有与强类型枚举相同的类型安全含义,但它允许你想到的语法调用。
作为旁注,一旦您担心使用std::tuple
对象的可读性影响,您可能希望切换到一个简单的struct
。
std::get
的索引模板参数的类型为 std::size_t
。作用域枚举不能隐式转换为其基础类型。因此,如果您坚持使用一个,则必须投射它。
auto arg1 = std::get<static_cast<int>(tpl::arg1)>(key);
如果要避免在演员表中提及基础类型
auto arg1 = std::get<static_cast<std::underlying_type_t<tpl>>(tpl::arg1)>(key);
相关文章:
- 使用枚举为数组编制索引是否安全?
- 枚举类的编译时索引器
- 我们应该如何使用枚举类进行索引(或者我们应该更好地避免这种情况)?
- 类与枚举类作为索引类型
- 如何通过索引访问枚举类
- 在编译时使用 和枚举作为索引分配数组的值 (C++)
- 使用索引设置矢量枚举时的奇怪行为
- C++枚举索引值
- 如何将C 枚举类枚举作为std ::阵列索引而没有明确的铸件
- std::get<0>(...) 和枚举索引
- 如何给枚举值的索引一个得到它?
- 阵列索引(转换为整数)用范围枚举
- 使用枚举作为索引访问 2D 向量
- 枚举类作为数组索引
- 通过其索引获取枚举值
- 在结构中自动索引枚举ID
- 重载枚举索引数组的std::get
- 使用枚举类值为数组编制索引时出现"Array subscript is not an integer"错误
- 从整数索引的for循环枚举到range-for
- 在编译时完全枚举 D 维数组的索引