检测单个枚举常量的类型

时间:2014-06-29 14:52:52

标签: c++ c++11 enums c++14 type-deduction

下面的代码打印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包含两个与enuma分开的b,则会发生这种情况。

问题:是否可以检测Test::a是使用bool进行初始化,Test::bint?在C ++ 17的任何反思研究组提案中是否有任何实验代码?

注意:我知道我可以通过将<{1}}替换为

来解决这个问题
Test

但我发现struct Test { static constexpr auto a = true; static constexpr auto b = 1; }; 版本的用法略显冗长。

2 个答案:

答案 0 :(得分:3)

不可能,我认为这是不可能的。

原因是ab是(在您的情况下未命名)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分开,那么这可能不是问题。