为什么const std :: random_device不可能?

时间:2016-01-31 16:16:12

标签: c++ random

我问自己这个问题为什么

#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;并不是那么难看?

这种设计有什么理由吗?

2 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:7)

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

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

  2. 该功能不会改变其操作对象的内部状态。

  3. 该函数访问thread-safe way中对象的状态。

  4. 这些都不适用于random_device::operator()。你会得到不同的结果; 这是功能的重点。对象内部的状态将受到请求(以某种方式)的影响。并且该功能最确定线程安全;在不同线程的同一个对象上调用它会导致所有不良的庄严。

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

    至于你的目标:

      

    我想让A级正确定义(doStuff()是一种const方法)现在我突然需要使用mutable std::random_device rd;那不丑吗?

    这取决于const的含义。显然#2已经出局,因为你将改变mutable状态。但是,对于&#34;相同结果&#34;的特定定义,您仍然可以提供#1。也就是说,&#34;东西&#34; doStuff确实在逻辑上是一致的。显然不是二进制相同,而是在函数行为的范围内。这足以成为const

    您甚至可以通过在互斥锁中包含对mutable RNG对象的访问权来提供#3。

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