以通用方式选择有效的随机枚举值

2024-04-04

假设我们有一个枚举类型E.

enum class E : underlying_type_of_E {
 v1 = uE1,
 v2 = uE2,
   //...
 vN = uEN
};

typedef typename std::underlying_type<E>::type uE;

一般来说,并非所有值uE是有效值E,因为我们可以选择它们之间的关系。是否有一种创建随机、有效的通用方法(在定义中命名,而不是可分配的),E 的值? 例如,这是行不通的:

std::mt19937 m;
std::uniform_int_distribution<uE> randomUE(0, std::numeric_limits<uE>::max());

E e = static_cast<E>( randomUE(m) );

because:

  1. 值范围不能从0开始
  2. 值范围不能以 std::numeric_limits::max() 结束
  3. 值范围可能根本不是一个范围 - 我们可以从 uE 中选择 E 的离散值,例如 {1, 3, 64, 272}。

鉴于所有枚举值在编译时都是已知的,我无法想象为什么这会以任何方式危险或容易出错。

至于为什么我想要这样的东西 - 我正在研究一种使用模板化基因存储的遗传算法。现在,我使用枚举作为染色体并将它们存储在std::vector<bool>其转换为std::vector<enumT>一经请求。这种方法的问题是突变会以给定的概率翻转随机位。这可能会导致问题,因为它可能会产生作为未命名枚举值的无效染色体。


如果您准备使用预处理器宏来创建enum类型和一些关于它的元数据,但这只是一个小麻烦:

  • 调用可变参数宏:

    ENUM(E,
         v1 = uE1,
         v2 = uE2,
         // ...
         vN = uEN);
    
  • 创建模板类Incrementing其中连续变量通过递增来初始化static默认情况下为成员,但可以从您的基础类型(例如int).

    static Incrementing<E, Underlying> __VA_ARGS__; \
    
  • 使用上面的值来初始化一个数组Incrementing值(需要一个operator Underlying() const成员)。

    static const Underlying values[] = { __VA_ARGS__ }; \
    

The values[]然后数组包含命名的枚举值......

我几年前写过这个概念的一个完全矫枉过正的版本here https://github.com/boost-vault/Miscellaneous/blob/master/benum_v1.zip,但考虑到您的简单要求,我建议从头开始。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以通用方式选择有效的随机枚举值 的相关文章

随机推荐