bqu*_*nin 64 c++ cardinality c++11 enum-class
是否有可能确定c ++的基数enum class:
enum class Example { A, B, C, D, E };
sizeof但是,我尝试使用它返回枚举元素的大小.
sizeof(Example); // Returns 4 (on my architecture)
有没有一种获得基数的标准方法(在我的例子中为5)?
Cam*_*ron 55
不是直接的,但你可以使用以下技巧:
enum class Example { A, B, C, D, E, Count };
然后基数可用(int)Example::Count.
当然,如果你自动分配枚举值,从0开始,这只能很好地工作.如果不是这样,你可以手动为Count分配正确的基数,这与必须保持一个单独的常量没有什么不同无论如何:
enum class Example { A = 1, B = 2, C = 4, D = 8, E = 16, Count = 5 };
一个缺点是编译器允许你Example::Count用作枚举值的参数 - 所以如果你使用它就要小心!(不过,我个人认为这在实践中并不是一个问题.)
Epo*_*ous 17
constexpr auto TEST_START_LINE = __LINE__;
enum class TEST { // Subtract extra lines from TEST_SIZE if an entry takes more than one 
    ONE = 7
  , TWO = 6
  , THREE = 9
};
constexpr auto TEST_SIZE = __LINE__ - TEST_START_LINE - 3;
这是从UglyCoder的答案中得出的,但却以三种方式改进了它.
BEGIN和SIZE)中没有额外的元素(Cameron的答案也有这个问题.)
它保留了UglyCoder相对于Cameron的答案的优势,即可以为调查员分配任意值.
一个问题(与UglyCoder共享但不与Cameron共享)是它使换行符和注释显着......这是意料之外的.所以有人可以在不调整TEST_SIZE计算的情况下添加带有空格或注释的条目.
Nea*_*gye 11
对于C ++ 17,您可以magic_enum::enum_count从lib https://github.com/Neargye/magic_enum使用:
magic_enum::enum_count<Example>() -> 4。
enum class TEST
{
    BEGIN = __LINE__
    , ONE
    , TWO
    , NUMBER = __LINE__ - BEGIN - 1
};
auto const TEST_SIZE = TEST::NUMBER;
// or this might be better 
constexpr int COUNTER(int val, int )
{
  return val;
}
constexpr int E_START{__COUNTER__};
enum class E
{
    ONE = COUNTER(90, __COUNTER__)  , TWO = COUNTER(1990, __COUNTER__)
};
template<typename T>
constexpr T E_SIZE = __COUNTER__ - E_START - 1;
有一个基于 X()-macros: image 的技巧,你有以下枚举:
enum MyEnum {BOX, RECT};
将其重新格式化为:
#define MyEnumDef \
    X(BOX), \
    X(RECT)
然后下面的代码定义了枚举类型:
enum MyEnum
{
#define X(val) val
    MyEnumDef
#undef X
};
以下代码计算枚举元素的数量:
template <typename ... T> void null(T...) {}
template <typename ... T>
constexpr size_t countLength(T ... args)
{
    null(args...); //kill warnings
    return sizeof...(args);
}
constexpr size_t enumLength()
{
#define XValue(val) #val
    return countLength(MyEnumDef);
#undef XValue
}
...
std::array<int, enumLength()> some_arr; //enumLength() is compile-time
std::cout << enumLength() << std::endl; //result is: 2
...
它可以通过 std::initializer_list 的技巧解决:
#define TypedEnum(Name, Type, ...)                                \
struct Name {                                                     \
    enum : Type{                                                  \
        __VA_ARGS__                                               \
    };                                                            \
    static inline const size_t count = []{                        \
        static Type __VA_ARGS__; return std::size({__VA_ARGS__}); \
    }();                                                          \
};
用法:
#define Enum(Name, ...) TypedEnum(Name, int, _VA_ARGS_)
Enum(FakeEnum, A = 1, B = 0, C)
int main()
{
    std::cout << FakeEnum::A     << std::endl
              << FakeEnun::count << std::endl;
}
Reflection TS,特别是最新版本的 Reflection TS 草案的[reflect.ops.enum]/2提供了以下get_enumerators TransformationTrait操作:
\n\n[reflect.ops.enum]/2
\nRun Code Online (Sandbox Code Playgroud)\ntemplate <Enum T> struct get_enumerators\n所有专业化
\nget_enumerators<T>均应满足要求TransformationTrait(20.10.1)。名为\n 的嵌套类型type指定满足\n 的元对象类型ObjectSequence,包含满足Enumerator并\n反映由 反映的枚举类型的枚举器的元素T。
草案的 [reflect.ops.objseq] 涵盖了ObjectSequence操作,特别是 [reflect.ops.objseq]/1 涵盖了get_size提取满足以下条件的元对象的元素数量的特征ObjectSequence:
\n\n[reflect.ops.objseq]/1
\nRun Code Online (Sandbox Code Playgroud)\ntemplate <ObjectSequence T> struct get_size;\n的所有特化
\nget_size<T>均应满足UnaryTypeTrait基本特征 的要求 (20.10.1)integral_constant<size_t, N>,其中N是对象序列中元素的数量。
因此,在 Reflection TS 中,要以其当前形式接受和实现,可以在编译时计算枚举的元素数量,如下所示:
\nenum class Example { A, B, C, D, E };\n\nusing ExampleEnumerators = get_enumerators<Example>::type;\n\nstatic_assert(get_size<ExampleEnumerators>::value == 5U, "");\n我们可能会在其中看到别名模板get_enumerators_v并get_type_v进一步简化反射:
enum class Example { A, B, C, D, E };\n\nusing ExampleEnumerators = get_enumerators_t<Example>;\n\nstatic_assert(get_size_v<ExampleEnumerators> == 5U, "");\n正如 Herb Sutter 的旅行报告所述:2018 年 6 月 9 日 ISO C++ 委员会夏季会议的夏季 ISO C++ 标准会议 (Rapperswil),Reflection TS 已被宣布为功能完整
\n\n\nReflection TS 功能完整:Reflection TS 已被宣布功能完整,并将在夏季进行主要评论投票。再次注意,TS\xe2\x80\x99s 当前基于模板元编程的语法只是一个占位符;所请求的反馈是关于设计的核心 \xe2\x80\x9cguts\xe2\x80\x9d 的,委员会已经知道它打算用更简单的编程模型替换表面语法,该模型使用普通的编译时代码而不是
\n<>风格的元编程。
最初计划用于 C++20,但目前还不清楚 Reflection TS 是否仍有机会进入 C++20 版本。
\n| 归档时间: | 
 | 
| 查看次数: | 41588 次 | 
| 最近记录: |