使用C ++进行枚举映射

时间:2016-09-22 09:30:08

标签: c++ templates enums

我需要在两组枚举之间进行映射。枚举之间的对应关系是一对一的。

例如

第一集:

Enum1{A, B, C, D};
Enumx...
Enumy...

第二组:

Enum2{A2, B2, C2, D2};
Enumx2...
Enumy2...

地图功能:

Enum1 map(Enum2);
Enumx map(Enumx2);
Enumy map(Enumy2);

我正在寻找一种优雅的方式来做这张地图。 我可以使用模板专业化吗?或者枚举被视为整数?

示例:

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);
    }
};

4 个答案:

答案 0 :(得分:1)

您可以使用特征:

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; };
// ...

然后,只要您拥有Enum1的值,就可以使用Enum2找到Enum1<VALUE>::value; 中的值:

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, "!");
}

它遵循一个最小的工作示例:

getClasses

答案 1 :(得分:1)

假设您的enum具有相同的值,您可以这样做:

template <typename E> struct MappingEnum;

template <typename E>
using MappingEnum_t = typename MappingEnum<E>::type;

template <> struct MappingEnum<Enum1>
{
    using type = Enum2;
};

然后

template <typename E>
MappingEnum_t<T> map(E e) { return static_cast<MappingEnum_t<T>>(e); }

答案 2 :(得分:0)

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)));
}

此转换级联非常明确,并支持枚举类。

对于较旧的C ++版本和没有class的枚举,static_cast<Enum2>(e)就足够了。

修改

使用模板专门化,您可以使用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)));
}

然后,您可以致电map(Enum1::A)。也适用于简单的非类枚举。

答案 3 :(得分:0)

除了您现在添加到问题中的静态强制转换之外,您还可以使用以前枚举中的值在等效枚举中设置值,从而使映射更容易/更明确: -

enum Enum1
{
    a = 1,
    b = 2,
};

enum Enum2
{
    z = a,
    y = b
};

还有一种方法可以将模板折叠成只需要指定目标......

template <typename targettype>
class Converter
{
    public:
    template<typename sourceType>
    static targettype Convert(sourceType from)
    {
        return static_cast<targettype>(from);
    }
};

可以调用为: -

Converter<Enum2>::Convert(someEnum1);