检测单个枚举常量的类型
Detecting the types of individual enumeration constants
下面的代码将unsigned int
打印为enum Test
中所有常量的底层类型
#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
struct Test
{
enum { a = true, b = 1 };
};
static_assert(std::is_same<
std::underlying_type_t<decltype(Test::a)>,
std::underlying_type_t<decltype(Test::b)>>::value, ""
);
int main()
{
int status;
auto const& bi = typeid(std::underlying_type_t<decltype(Test::a)>);
std::cout << abi::__cxa_demangle(bi.name(), 0, 0, &status); // unsigned int
}
<<p> 生活例子/strong>。如果Test
与a
和b
一样包含两个单独的enum
,也会发生这种情况。
问题:是否有可能检测到Test::a
用bool
初始化,Test::b
用int
初始化?在c++ 17的任何反射研究小组的建议中,有关于这个的实验代码吗?
注意:我知道我可以通过用
替换Test
来解决它struct Test
{
static constexpr auto a = true;
static constexpr auto b = 1;
};
但是我发现enum
版本在使用上稍微不那么啰嗦。
这是不可能的我认为这是非常不可能的。
原因是a
和b
是(在您的情况下未命名的)enum
的值。因此,根据定义,它们属于enum
类型,即:相同类型。用于初始化它们和它们各自的类型的表达式仅用于"计算"enum
的基础类型,而不是任何单个值的基础类型。
考虑到这个事实,我认为即使反射也不会帮助恢复信息,因为当您查看enum
的值时,初始化表达式的类型被抽象掉了。
你需要的是一个更深层次的检查,你需要访问用于初始化值的表达式。这意味着编译器将不得不为每个变量、值等存储大量额外的信息(因为这将是一件普遍的事情,而不仅仅是enum
)。
考虑这是什么意思:
- 增加编译时间
- 编译 时内存使用量增加
- 每个值现在都有效地具有两种类型,声明的类型和从 初始化的表达式的类型。
最后一点是我认为这门语言真正的灾难。值应该具有单一类型,用于初始化值的表达式不应该以任何方式可访问。这就是抽象的意义所在,打破它可能会导致各种微妙的依赖关系和大量的复杂性。
免责声明:这只是我个人的观点,我不能代表委员会或工作组的任何人。
可以用以下方法区分int型枚举值和非int型枚举值:
struct Test
{
enum : short { a = true };
enum : int { b = 1 };
// enum : bool { c = false };
};
不幸的是,VC2010未能将bool编译为基础类型,这可能不被视为整型。如果你的用例只需要将整型与非整型分开,这可能不是问题。
相关文章:
- 在有符号基础类型枚举的位域上溢出
- 在编译时将强类型枚举器转换为其基础类型?
- 如果 int 是"not within the enums range",为什么将 int 转换为强类型枚举会编译?
- 类型枚举的变量不是类型名称
- 枚举常量在C和C++中表现不同
- 强类型枚举的语法实现错误
- 枚举与强类型枚举
- 错误:T没有命名类型-用于使用强类型枚举的专门化
- 有没有办法不警告 gcc 中开关缺少"COUNT"枚举常量?
- 如何使用强类型枚举
- QT:将强类型枚举参数传递到插槽
- 在类定义中声明类型(枚举、结构等)会增加代码大小
- Visual Studio 11 (beta) 中的强类型枚举类
- 使用强类型枚举对类型和子类型进行建模
- 不允许将强类型枚举用作同一基础类型的参数
- 如何正确使用C++强类型枚举
- 使C++软件包和C#软件包访问相同枚举/常量int的最佳方法
- 带有强类型枚举的模板参数推导
- 检测单个枚举常量的类型
- std::min未能将枚举常量解释为有效的整数类型(g++4.6.3)