在模板函数中,如果输入的类型是枚举类,我该如何使用 std::underlying_type?

s4e*_*eed 2 c++ templates sfinae static-cast enum-class

我有一段代码返回给定数字的某些位的值(我也使用 static_cast 将枚举类计算为一个数字)。

template<typename Type>
bool get_bits(Type input, uint8_t offset, uint8_t n, Type* destination)
{
    if (offset + n> sizeof(Type) * 8)
        return false;

    Type bitmask = 0;

    for (int i = 0; i < n; ++i)
        bitmask |= (1 << i);

    *destination = static_cast<Type>(input >> offset & bitmask);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

该函数试图返回的值n的位input由开始offset。它适用于整数类型,但是当我尝试将它与枚举类一起使用时,编译失败。我尝试使用std::underlying_type然后它适用于枚举类但不适用于整数类型:|。我怎样才能将它用于他们两个?我的意思是,如果类型是枚举类,我想将输入转换为它的underlying_type,执行一些按位运算,然后将结果(使用static_cast)存储到目标。但是对于没有underlying_type 的整数类型,不应该进行这些转换。

Sto*_*ica 5

如果您经常需要它,可以通过std::underlying_type. 像这样的东西

namespace detail {
  template<typename T, bool = std::is_enum<T>::value>
  struct underlying_type { using type = T; };

  template<typename T>
  struct underlying_type<T, true> : ::std::underlying_type<T> {};
}
Run Code Online (Sandbox Code Playgroud)

当您使用detail::underlying_type<T>替换时,也会出现在默认参数中。当提供的类型不是枚举时,主模板匹配参数(隐式),并且公开的typeT.

当提供的类型是枚举(并且只有这样)时,才会使用特化。它所做的一切都是向标准特征前进。