检测单个枚举常量的类型

Detecting the types of individual enumeration constants

本文关键字:类型 枚举常量 单个 检测      更新时间:2023-10-16

下面的代码将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>。如果Testab一样包含两个单独的enum,也会发生这种情况。

问题:是否有可能检测到Test::abool初始化,Test::bint初始化?在c++ 17的任何反射研究小组的建议中,有关于这个的实验代码吗?

注意:我知道我可以通过用

替换Test来解决它
struct Test
{
    static constexpr auto a = true;
    static constexpr auto b = 1;
};

但是我发现enum版本在使用上稍微不那么啰嗦。

这是不可能的我认为这是非常不可能的。

原因是ab是(在您的情况下未命名的)enum的值。因此,根据定义,它们属于enum类型,即:相同类型。用于初始化它们和它们各自的类型的表达式仅用于"计算"enum的基础类型,而不是任何单个值的基础类型。

考虑到这个事实,我认为即使反射也不会帮助恢复信息,因为当您查看enum的值时,初始化表达式的类型被抽象掉了。

你需要的是一个更深层次的检查,你需要访问用于初始化值的表达式。这意味着编译器将不得不为每个变量、值等存储大量额外的信息(因为这将是一件普遍的事情,而不仅仅是enum)。

考虑这是什么意思:

  • 增加编译时间
  • 编译
  • 时内存使用量增加
  • 每个值现在都有效地具有两种类型,声明的类型和从
  • 初始化的表达式的类型。

最后一点是我认为这门语言真正的灾难。值应该具有单一类型,用于初始化值的表达式不应该以任何方式可访问。这就是抽象的意义所在,打破它可能会导致各种微妙的依赖关系和大量的复杂性。

免责声明:这只是我个人的观点,我不能代表委员会或工作组的任何人。

可以用以下方法区分int型枚举值和非int型枚举值:

struct Test
{
  enum : short { a = true };
  enum : int   { b = 1    };
  // enum : bool { c = false };
};

不幸的是,VC2010未能将bool编译为基础类型,这可能不被视为整型。如果你的用例只需要将整型与非整型分开,这可能不是问题。