std::random_device::random_device

来自cppreference.com
< cpp‎ | numeric‎ | random‎ | random device
 
 
 
 
 
random_device() : random_device( /* 由实现定义 */ ) {}
(1) (C++11 起)
explicit random_device( const std::string& token );
(2) (C++11 起)
random_device( const random_device& ) = delete;
(3) (C++11 起)
1) 以实现定义的 token 默认构造新的 std::random_device 对象。
2) 构造新的 std::random_device 对象,若提供则以实现定义行为利用实参 token
3) 复制构造函数被弃置:std::random_device 不可复制或移动。

异常

失败时抛出从 std::exception 派生的实现定义异常。

注解

libstdc++ 中的实现期待 token 指名随机字节的源。可能的记号值包括 "default""rand_s""rdseed""rdrand""rdrnd""/dev/urandom""/dev/random""mt19937" 和指定 mt19937 引擎的种子的整数字符串。(除 "default" 之外的记号仅在某些目标上可用。)

libc++ 中的实现在配置以字符设备为源时,期待 token 为在从它读取时产生随机数的字符设备的名字;否则它期待 token"/dev/urandom"

若提供不支持的记号则 libstdc++ 与 libc++ 均抛出异常。Microsoft STL 完全忽略记号。

示例

演示 Linux 上 std::random_device 的常见可用类型

#include <iostream>
#include <random>
 
void demo(std::random_device&& rd)
{
    static std::uniform_int_distribution<int> d(0, 9);
    for (int n = 0; n != 10; ++n)
        std::cout << d(rd) << ' ';
    std::cout << '\n';
}
 
int main()
{
    // 注意:如何利用所提供的 token 是由实现定义的!
 
    // Linux 上 random_device 的默认 token 通常为 /dev/urandom
    demo(std::random_device {});
 
    // 请求 /dev/random,当熵为空时阻塞
    // libstdc++ 上可用,msvc++ 忽略,libc++ 可能抛异常(2022 年十一月)
    demo(std::random_device {"/dev/random"});
 
    // 请求非阻塞的 /dev/urandom,保证不使用 RDRAND
    // libstdc++ 和 libc++ 上可用,msvc++ 忽略(2022 年十一月)
    demo(std::random_device {"/dev/urandom"});
 
    // 请求 "hw",将使用基于硬件的随机生成,如 rdrand
    // libstdc++ 上可用,msvc++ 忽略,libc++ 抛异常(2022 年十一月)
    demo(std::random_device {"hw"});
}

可能的输出:

9 5 2 7 5 9 4 1 0 7 
4 7 6 5 1 5 5 1 8 6 
3 3 6 1 4 1 4 1 0 2 
4 6 3 9 1 9 4 0 9 3

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
P0935R0 C++11 默认构造函数为 explicit 使之为隐式