std::get使用enum class作为索引报错及索引类型咨询
关于std::get与enum class索引的问题解答
首先明确说下std::get的索引要求:它的模板参数必须是编译期可确定的整数类型常量(比如int、size_t这类),而且这个值得落在tuple的有效索引范围内(0到元素个数-1)。
你遇到的编译器错误,核心原因是强类型枚举(enum class)的成员无法隐式转换为整数类型。哪怕你给enum class指定了底层类型(比如enum class tpl: int { ... }),它依然是强类型的,不会自动转成int或者size_t,而std::get的模板参数需要的是整数类型的编译期常量,所以直接传tpl::arg1会匹配不到合适的重载。
那能不能通过定义enum class时指定类型解决?其实指定底层类型只是改变枚举成员的存储类型,没法改变它的强类型特性——还是得显式转换才能用在std::get里。
给你几个实用的解决办法:
- 显式转换枚举成员:直接把枚举值转成整数类型,比如:
auto _arg1 = std::get<static_cast<std::size_t>(tpl::arg1)>(key); - 写个constexpr转换辅助函数:如果觉得每次写static_cast麻烦,可以封装一个常量表达式函数:
constexpr std::size_t to_index(tpl val) { return static_cast<std::size_t>(val); } // 使用方式 auto _arg1 = std::get<to_index(tpl::arg1)>(key); - 用命名空间包裹普通枚举:如果不想用强类型枚举,又要避免名字冲突,可以把普通枚举放进命名空间:
namespace tpl { enum : std::size_t { arg1 = 0, arg2 = 1, arg3 = 2 }; } // 使用方式和之前一样,还不会有名字冲突 auto _arg1 = std::get<tpl::arg1>(key);
内容的提问来源于stack exchange,提问作者makurisan
相关产品推荐
相关产品推荐

