【发布时间】:2021-09-22 13:11:12
【问题描述】:
我正在尝试为可以索引的类型使用类型特征,例如std::vector,它应该包括枚举类型,因为我可以将它们转换为它们的底层类型。
到目前为止,我已经写了以下特征。
#include <iostream>
#include <type_traits>
#include <cinttypes>
#include <vector>
#include <utility>
template<typename T>
struct is_unsigned_integral :
std::integral_constant<
bool,
std::is_integral<T>::value &&
std::is_unsigned<T>::value
> {};
template<typename T>
inline constexpr auto is_unsigned_integral_v =
is_unsigned_integral<T>::value;
template<typename, typename = void>
struct is_index : std::false_type {};
template<typename T>
struct is_index<
T,
std::enable_if_t<
is_unsigned_integral_v<
std::conditional_t<
std::is_enum_v<T>,
std::underlying_type_t<T>,
T
>
>
>
> : std::true_type {};
template<typename T>
inline constexpr auto is_index_v = is_index<T>::value;
enum class idx : unsigned int {};
int main() {
static_assert(is_index_v<unsigned int>, "");
static_assert(is_index_v<idx>, "");
return 0;
}
但我收到以下错误消息
type_traits:2009:15: error:
only enumeration types have underlying types
typedef __underlying_type(_Tp) type;
我会期待以下
std::conditional_t<
std::is_enum_v<T>,
std::underlying_type_t<T>,
T
>
将八位计算为T 或基础类型为T 是enum。
我将如何进行这项工作?
【问题讨论】:
-
出于好奇,您使用的是什么编译器?使用 gcc,静态断言失败(原因是您的错误消息所说的,但由于 SFINAE,它不应该是错误)godbolt.org/z/cs7Gbjc3n
-
@463035818_is_not_a_number 在replit.com 中使用时使用clang。我目前正在尝试更适应类型特征和元编程:)
-
还有clang我得到一个不同的错误godbolt.org/z/xn5PfscPG,虽然我实际上不确定因为
std::underlying_type<T>是UB直到C++20,当T不是枚举时,保证什么, -
@463035818_is_not_a_number 我已经在其他使用 gcc / clang 的在线编译器中尝试过你的答案,它似乎在 gcc 下工作正常,但 clang 仍然给出错误
-
clang godbolt.org/z/Tqe8YG3vT没有错误
标签: c++ metaprogramming typetraits