[英]Enum mapping in C++
I need to do a mapping between two sets of enums. 我需要在两组枚举之间进行映射。 The correspondence between enums is one to one.
枚举之间的对应关系是一对一的。
For example 例如
The first set: 第一组:
Enum1{A, B, C, D};
Enumx...
Enumy...
The second set: 第二组:
Enum2{A2, B2, C2, D2};
Enumx2...
Enumy2...
The map function: 地图功能:
Enum1 map(Enum2);
Enumx map(Enumx2);
Enumy map(Enumy2);
I'm searching for an elegant manner of doing this map. 我正在寻找一种制作这张地图的优雅方式。 Can I use template specialization?
我可以使用模板专业化吗? or the enums are seen all as integers?
还是将枚举全部视为整数?
Example: 例:
class MapHelper{
public:
template<typename From, To>
static To map(From from);
template<>
static Enum1 map<Enum2, Enum1>(Enum2 from){
return static_cast<Enum1>(from);
}
};
You can use traits: 您可以使用特征:
template<Enum1 V> struct ToEnum2;
template<> struct ToEnum2<Enum1::A> { static constexpr Enum2 value = Enum2::A; };
template<> struct ToEnum2<Enum1::B> { static constexpr Enum2 value = Enum2::B; };
// ...
Then, whenever you have a value from Enum1
, you can find the one from Enum2
using: 然后,只要有
Enum1
的值,就可以使用以下方法从Enum2
找到一个:
Enum1<VALUE>::value;
It follows a minimal, working example: 它遵循一个最小的有效示例:
enum class Enum1 { A, B };
enum class Enum2 { C, D };
template<Enum1 E> struct Map;
template<> struct Map<Enum1::A> { static constexpr Enum2 value = Enum2::C; };
template<> struct Map<Enum1::B> { static constexpr Enum2 value = Enum2::D; };
int main() {
static_assert(Map<Enum1::A>::value == Enum2::C, "!");
static_assert(Map<Enum1::B>::value == Enum2::D, "!");
}
Assuming your enum
have same values, You may do: 假设您的
enum
具有相同的值,则可以执行以下操作:
template <typename E> struct MappingEnum;
template <typename E>
using MappingEnum_t = typename MappingEnum<E>::type;
template <> struct MappingEnum<Enum1>
{
using type = Enum2;
};
And then 接着
template <typename E>
MappingEnum_t<T> map(E e) { return static_cast<MappingEnum_t<T>>(e); }
C++11 solution: C ++ 11解决方案:
#include <type_traits>
template<typename From, typename To>
To map(From e) {
return static_cast<To>(
static_cast<typename std::underlying_type<To>::type>(
static_cast<typename std::underlying_type<From>::type>(e)));
}
This casting cascade is very explicit and supports enum classes. 此强制转换级联非常明确,并支持枚举类。
For older C++ versions and for enums without class
, static_cast<Enum2>(e)
would suffice. 对于较旧的C ++版本和不带
class
枚举, static_cast<Enum2>(e)
就足够了。
Edit: 编辑:
With template specialization, you can use map
without specifying any types explicitly: 使用模板专业化,可以使用
map
而不显式指定任何类型:
enum class Enum1: int {A, B, C, D};
enum class Enum2: char {A1, B1, C1, D1};
template<typename T>
struct target_enum {
};
template<>
struct target_enum<Enum1> {
typedef Enum2 type;
};
template<typename From>
typename target_enum<From>::type map(From e) {
typedef typename target_enum<From>::type To;
return static_cast<To>(
static_cast<typename std::underlying_type<To>::type>(
static_cast<typename std::underlying_type<From>::type>(e)));
}
You can then call map(Enum1::A)
. 然后,您可以调用
map(Enum1::A)
。 Also works with simple, non-class enums. 也适用于简单的非类枚举。
In addition to the static casting that you've now added to your question, you can make the mapping easier / more explicit by setting the values in equivalent enums using the values from a previous enum:- 除了现在已经添加到问题中的静态强制转换之外,您还可以使用上一个枚举的值在等效枚举中设置值,从而使映射更容易/更明确:
enum Enum1
{
a = 1,
b = 2,
};
enum Enum2
{
z = a,
y = b
};
And a way to collapse template into only needing to specify target... 还有一种将模板折叠成只需要指定目标的方法...
template <typename targettype>
class Converter
{
public:
template<typename sourceType>
static targettype Convert(sourceType from)
{
return static_cast<targettype>(from);
}
};
callable as:- 可称为:-
Converter<Enum2>::Convert(someEnum1);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.