C++ std::random 和枚举类

标签 c++ random visual-c++ enums

我有一个关于更现代的 C++“首选”样式的挑剔问题。

假设我想使用 std::random 的内容来从 enum class 中选择一个值。我怎样才能骗过它?我们在这里谈论一些非常基本的东西,第一个选择工作得很好,但 Visual Studio 责备我(正确地)使用裸枚举:

enum Direction:uint8_t {
    Left, Right
};

std::uniform_int_distribution<uint8_t> direction(Direction::Left, Direction::Right);

// and so on...

我很惊讶 enum-base 可以用于经典的 enum。但是,简单地将单词 class 添加到组合中会导致整个 shebang 无法编译。

enum class Direction:uint8_t {
    Left, Right
};

std::uniform_int_distribution<uint8_t> direction(Direction::Left, Direction::Right);

// Severity Code    Description Project File    Line    Suppression State
// Error    C2338   invalid template argument for uniform_int_distribution:
//    N4659 29.6.1.1 [rand.req.genl]/1e requires one of short, int, long, long long, unsigned short, 
//    unsigned int, unsigned long, or unsigned long long 
//    C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\
//    include\random    1863    

等等。 =)

为了解决这个问题,我当然可以放下我的骄傲和原则,但我想遵守现代标准。

如果有人想像这样洗牌 enum 时有人有一些聪明的解决方法或其他最佳实践风格的东西,我会很高兴。

最佳答案

enumenum class 都有问题:它们不知道它们的大小,它们不能被迭代等。作为替代,您可以使用 std::variant 与虚拟类型:

struct Left {};
struct Right {};
using Direction = std::variant<Left, Right>;

template<typename V, typename E, std::size_t idx = 0>
auto constexpr cast = [] { // written once, works for any "enum"
    if constexpr (std::is_same_v<std::variant_alternative_t<idx, V>, E>) return idx;
    else return cast<V, E, idx + 1>;
}();

std::uniform_int_distribution direction{cast<Direction, Left>, cast<Direction, Right>};

作为奖励,现在您可以获得“枚举”中元素的数量:

static_assert(std::variant_size_v<Direction> == 2);

你甚至可以遍历它们的枚举器:

template<typename F, typename... Es> // written once, works for any "enum"
constexpr void for_each(F f, std::variant<Es...> const&) {
    (..., (void)f(Es{})); // void cast to ignore possible operator,() overloading
}

int main() {
    for_each([](auto enumerator) {
        std::cout << cast<Direction, decltype(enumerator)> << ' ';
    }, Direction{});
}

关于C++ std::random 和枚举类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69379497/

相关文章:

c++ - 一旦达到每个值就执行 C++

c++ - MSVC 中的模板模板参数错误,但不是 Clang。为什么?

c++ - 在插入期间检测周期

c++ - 使用 CRTP 继承

c++ - 将包含重音字符的 UTF-8 字符串转换为 UTF-16

c - while 循环导致函数在 c 中返回 0

java - 我怎样才能打乱一个单词的字母?

language-agnostic - Code Golf : MSM Random Number Generator

c++ - 将数组的所有点设置为 0 对重新分配动态内存有不同的影响

visual-c++ - Visual c++ OpenCV 2.1 contains()