在编译时将枚举值映射到带有模板的相应类型?

如何解决在编译时将枚举值映射到带有模板的相应类型?

我有一个想法,在编译时使用模板将枚举值映射到相应的数据类型。我该怎么做?

例如


enum DataType {
  UNSINGED_INT; // uint32_t
  INT; // int32_t
  UNSIGNED_CHAR; // uint8_t
  CHAR; // int8_t
}

auto type = MapToDataType<DataType::UNSIGNED_CHAR>; // type will be uint8_t in this case

解决方法

如果您的 enum 包含可转换为 int 的值序列,没有空洞,并且从零开始(如您的示例中所示),您可以使用 std::tuple 作为类型映射和std::tuple_element 提取所需的类型。

所以,写一个辅助结构如下

template <DataType dt>
struct MapToDataType_helper
 {
   using type = typename std::tuple_element<
     static_cast<std::size_t>(dt),std::tuple<std::uint32_t,std::int32_t,std::uint8_t,std::int8_t>
                   >::type;
 };

您的地图是一个简单的模板,使用

template <DataType dt>
using MapToDataType = typename MapToDataType_helper<dt>::type;

例如,您可以验证

static_assert( std::is_same_v<MapToDataType<DataType::UNSIGNED_CHAR>,std::uint8_t> );
,
template <DataType> struct MapToDataTypeHelper {};
template <> struct MapToDataTypeHelper<INT> {using type = int;};
template <> struct MapToDataTypeHelper<UNSIGNED_INT> {using type = unsigned int;};
// ...

template <DataType X> using MapToDataType = typename MapToDataTypeHelper<X>::type;
MapToDataType<INT> x; // int x;
,

首先你特化一个类模板,然后你使用别名模板:

#include <cstdint>

enum class DataType {
    UNSIGNED_CHAR,UNSIGNED_INT,CHAR,INT
};

template <DataType> struct MapToDataType;
template <> struct MapToDataType_t<DataType::UNSIGNED_CHAR> { using type = std::uint8_t; };
template <> struct MapToDataType_t<DataType::UNSIGNED_INT>  { using type = std::unit32_t; };
template <> struct MapToDataType_t<DataType::CHAR>          { using type = std::int8_t; };
template <> struct MapToDataType_t<DataType::INT>           { using type = std::nit32_t; };

template <DataType T>
using MapToDataType = typename MapToDataType_t<T>::type;
,

一些标签类型和值来携带编译时值和类型:

template<auto x>
using constant_t = std::integral_constant<std::decay_t<decltype(x)>,x>;
template<auto x>
constexpr constant_t<x> constant{};
template<class T>
struct tag_t{using type=T;};
template<class T>
constexpr tag_t<T> tag{};

template<class X>
constexpr void type_map( X ) {}

template<auto X>
using get_type = typename decltype(type_map(constant<X>))::type;

好的,机器完成了。

现在只需添加这些:

    inline auto type_map( constant_t<DataType::UNSIGNED_INT> ) { return tag<std::uint32_t>; }
    inline auto type_map( constant_t<DataType::INT> ) { return tag<std::int32_t>; }
    inline auto type_map( constant_t<DataType::UNSIGNED_CHAR> ) { return tag<std::uint8_t>; }
    inline auto type_map( constant_t<DataType::CHAR> ) { return tag<std::int8_t>; }

它有效。

支持其他枚举只是将 type_map 重载添加到相关 enum 的命名空间中。

#define TYPE_MAP(FROM,...) \
  inline auto type_map( constant_t<FROM> ) { return tag<__VA_ARGS__>; }

可以让它不那么冗长。

get_type 现在可以在任何设置了相同机制的枚举上统一工作。

Live example

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?