简体   繁体   English

枚举的 C++ 模板特化

[英]C++ template specialization for enum

I want to map known type to enum value defined by myself.我想将已知类型映射到我自己定义的枚举值。

enum class MyType : uint8_t {
    Int8,
    Uint8,
    Int16,
    Uint16,
    Int32,
    Uint32,
    ... // some other primitive types.
};

template <typename T>
constexpr uint8_t DeclTypeTrait();

template <>
constexpr uint8_t DeclTypeTrait<int8_t>() {
  return static_cast<uint8_t>(MyType::Int8);
}
... // Specialize for each known number type.

Also for any enum type defined by user, I want to map it to Int32.同样对于用户定义的任何枚举类型,我想将其映射到 Int32。 User must define his enum class on int32_t.用户必须在 int32_t 上定义他的枚举类。

using Enumeration = int32_t;

// Some user defined enum.
enum class CameraKind : Enumeration { 
    Perspective, 
    Orthographic 
};

So I implement DeclTypeTrait like this:所以我像这样实现 DeclTypeTrait :

template <typename T,
          class = typename std::enable_if<std::is_enum<T>::value>::type>
constexpr uint8_t DeclTypeTrait() {
  return static_cast<uint8_t>(MyType::Int32);
}

But I got error: "call to 'DeclTypeTrait' is ambiguous"但我收到错误:“调用 'DeclTypeTrait' 不明确”

candidate function [with T = CameraKind]
candidate function [with T = CameraKind, $1 = void]

My question is how to accomplish this:我的问题是如何做到这一点:

// If a have a variable of known types or any enum on int32.
int8_t v1;
CameraKind camera;
std::string s;

DeclTypeTrait<decltype(v1)>() -> MyType::Int8
DeclTypeTrait<decltype(camera)>() -> MyType::Int32
DeclTypeTrait<decltype(s)>() // Report compile error is OK.

Use a class template will be much simpler for your case.对于您的情况,使用类模板会简单得多。

template <typename T, typename = std::void_t<>>
struct DeclTypeTraitT {
};

template <typename T>
inline constexpr uint8_t DeclTypeTrait = DeclTypeTraitT<T>::value;

template <>
struct DeclTypeTraitT<int8_t> {
    static constexpr uint8_t value = static_cast<uint8_t>(MyType::Int8);
};

template <typename T>
struct DeclTypeTraitT<T, std::enable_if_t<std::is_enum_v<T>>> {
    static constexpr uint8_t value = static_cast<uint8_t>(MyType::Int32);
};

Then然后

CameraKind camera;
static_assert(DeclTypeTrait<decltype(camera)> == static_cast<uint8_t>(MyType::Int32));

Demo演示


As @HolyBlackCat saying, if you want to map the underlying type, you can use正如@HolyBlackCat 所说,如果你想映射底层类型,你可以使用

template <typename T>
struct DeclTypeTraitT<T, std::enable_if_t<std::is_enum_v<T>>> {
    static constexpr uint8_t value = DeclTypeTrait<std::underlying_type_t<T>>;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM