C++17编译期实现两个enum枚举值相互映射的方案求助
C++17 编译期枚举映射实现方案
方案1:模板特化(完全匹配要求的调用形式)
直接通过模板全特化实现映射,所有值编译期确定,零运行时开销:
#include <type_traits> // 枚举定义(补全了enum class标识与语法标点) enum class NAMES { A, B, C }; enum class LASTNAMES { A, B, C }; struct Mapper { template<NAMES n> struct get; }; // 逐个定义映射规则,新增映射只需加对应特化即可 template<> struct Mapper::get<NAMES::A> { static constexpr LASTNAMES value = LASTNAMES::A; }; template<> struct Mapper::get<NAMES::B> { static constexpr LASTNAMES value = LASTNAMES::B; }; template<> struct Mapper::get<NAMES::C> { static constexpr LASTNAMES value = LASTNAMES::C; };
调用效果完全符合需求:
Mapper::get<NAMES::A>::value编译期返回LASTNAMES::AMapper::get<NAMES::C>::value编译期返回LASTNAMES::C
方案2:constexpr数组映射(适合映射项多的场景)
如果枚举值数量多,逐个写特化太繁琐,可以用C++17的constexpr数组实现统一映射,性能和特化方案完全一致:
#include <utility> #include <cstdlib> enum class NAMES { A, B, C }; enum class LASTNAMES { A, B, C }; struct Mapper { private: // 映射表,新增映射只需要修改这个数组即可 static constexpr std::pair<NAMES, LASTNAMES> mapping_table[] = { {NAMES::A, LASTNAMES::A}, {NAMES::B, LASTNAMES::B}, {NAMES::C, LASTNAMES::C}, }; template<NAMES n> static constexpr LASTNAMES lookup() { for (const auto& item : mapping_table) { if (item.first == n) return item.second; } // 编译期触发错误,提示缺少对应映射 static_assert([]{ return false; }(), "Missing mapping for input NAMES enum value"); return {}; } public: template<NAMES n> struct get { static constexpr LASTNAMES value = lookup<n>(); }; };
调用方式和方案1完全相同。
整数键映射实现
如果需要用整数作为键做映射,只需要调整模板参数类型即可:
enum class LASTNAMES { A, B, C }; struct Mapper { template<int key> struct get; }; template<> struct Mapper::get<1> { static constexpr LASTNAMES value = LASTNAMES::A; }; template<> struct Mapper::get<2> { static constexpr LASTNAMES value = LASTNAMES::B; }; template<> struct Mapper::get<3> { static constexpr LASTNAMES value = LASTNAMES::C; };
调用示例:Mapper::get<1>::value 编译期返回 LASTNAMES::A
内容的提问来源于stack exchange,提问作者Mateo Terselich
相关产品推荐
相关产品推荐

