以常规方式选择有效的随机枚举值
Selecting a valid random enum value in a general way
假设我们有一个枚举类型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) );
因为:
- 值范围不能从 0 开始
- 值范围不能以 std::numeric_limits::max(( 结尾
- 值范围可能根本不是一个范围 - 我们可以从 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__ };
然后,values[]
数组包含命名的枚举值。
我多年前在这里写的这个概念有一个完全矫枉过正的版本,但鉴于您的简单要求,我建议从头开始。
相关文章:
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 随机生成一个没有重复元素的枚举数组 (C++)
- 以最新的C 的类型安全方式从枚举中随机选择元素
- 生成无连续重复的随机枚举
- C++ 随机将枚举类型分配给变量
- 如何在 c++ 中从枚举返回随机元素
- 在C++中创建一个具有随机枚举类型的Card对象
- 以常规方式选择有效的随机枚举值