为什么 const st::random_device 是不可能的

Why is a const std::random_device not possible?

本文关键字:不可能 device random const st 为什么      更新时间:2023-10-16

我在问自己为什么

#include <random>
struct A{     
   std::random_device rd; // or any other generator std::mersenne_twister...
   void doStuff() const {
       auto v = rd();
   }
};
const A a;  
a.doStuff(); 

不起作用,因为random_device::operator()不是const.

我想也许随机设备在恒定时仍然可以使用,但不能再次播种,但事实并非如此(内部状态显然在std::random_device中是不可改变的(......

我想正确定义 A 类(doStuff()是一个 const 方法(,现在我突然需要使用 mutable std::random_device rd; 这不是很丑吗?

这种设计有什么原因吗?

const可以意味着很多事情。它可能意味着以下任何或所有内容:

  1. 给定相同的对象状态和参数,将发生相同的结果。

  2. 该函数不会更改其操作对象的内部状态。

  3. 该函数以线程安全的方式访问对象的状态。

这些都不适用于random_device::operator().你会得到不同的结果;这就是函数的重点。对象内部的状态将受到请求的影响(以一种或另一种方式(。而且该功能肯定不是线程安全的;从不同的线程在同一个对象上调用它可能会导致所有糟糕的庄园。

任何RNG也是如此。从 RNG 获取随机数本质上是一个非常量过程。这就是为什么 C++11 RNG 的设计要求operator()不被声明为const .

至于你的目标:

我想正确定义 A 类(doStuff()是一个 const 方法(,现在我突然需要使用 mutable std::random_device rd; 这不是很丑吗?

这取决于你的意思 const .显然#2已经出来了,因为您将更改mutable状态。但是,您仍然可以为"相同结果"的特定定义提供 #1。也就是说,doStuff所做的"东西"在逻辑上是一致的。显然不是二进制相同,但在函数行为的范围内。这足以const.

您甚至可以提供 #3,方法是将对 mutable RNG 对象的访问权限包装在互斥锁中。

像这样的案例正是发明mutable的原因。它并不丑陋;您只是将该功能用于其设计目的。允许您以逻辑上const调用的方式访问某些非const对象。

>std::randome_device::operator()()是非const的,因为它可能会修改对象的内部状态。 std::random_device可以是伪随机数生成器,它使用内部状态来生成数字。每次生成一个数字时,您都必须修改内部状态,否则每次都会得到相同的数字。