下面的代码打印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
}
Live Example。如果Test
包含两个与enum
和a
分开的b
,则会发生这种情况。
问题:是否可以检测Test::a
是使用bool
进行初始化,Test::b
是int
?在C ++ 17的任何反思研究组提案中是否有任何实验代码?
注意:我知道我可以通过将<{1}}替换为
来解决这个问题Test
但我发现struct Test
{
static constexpr auto a = true;
static constexpr auto b = 1;
};
版本的用法略显冗长。
答案 0 :(得分:3)
不可能,我认为这是不可能的。
原因是a
和b
是(在您的情况下未命名)enum
的值。因此,根据定义,它们是enum
的类型,意思是:相同类型。用于初始化它们的表达式和它们的各自的类型仅用于“计算”enum
的基础类型,而不是用于任何单个值。
考虑到这一点,我认为即使反射也无助于恢复信息,因为当您查看enum
的值时,初始化表达式的类型会被抽象掉。
您需要的是更深层次的检查,您需要访问用于初始化值的表达式。这意味着编译器必须为每个变量,值等存储大量附加信息(因为这不仅仅是enum
s的一般情况。)
考虑一下这意味着什么:
最后一点是我认为语言真正的灾难。值应该只有一个类型,用于初始化值的表达式不应该以任何方式访问。这就是抽象的意义所在,打破它会导致各种微妙的依赖关系和很多复杂性。
免责声明:这只是我个人的意见,我不能代表委员会或工作组中的任何人发言。
答案 1 :(得分:1)
您可以将枚举值与非整数区分开来,如下所示:
struct Test
{
enum : short { a = true };
enum : int { b = 1 };
// enum : bool { c = false };
};
不幸的是,VC2010无法将bool编译为基础类型,这可能不被视为整数类型。如果您的用例仅需要将int与非ints分开,那么这可能不是问题。