use*_*865 10 c++ random const mutable c++11
处理(否则)包含C++ 11随机类的随机生成器调用的常量函数的正确方法是什么?您是否应该放弃函数的常量标志,还是将生成器和分布声明为类的可变元素?一个最小的例子(不编译)可能是:
#include <random>
class foo
{
std::mt19937 MyGenerator;
std::normal_distribution<precision_type> gauss;
double get_rnd() const {return gauss(MyGenerator);}
};
Run Code Online (Sandbox Code Playgroud)
Ben*_*igt 11
这实际上取决于您为const
成员访问提供的语义.
对于标准类,const
从多个线程同时调用成员是线程安全的.const
除非RNG完全是线程安全的(不const
使用),否则让RNG变异的成员会破坏这一点.
您不必以相同的方式设计类,但其他开发人员可能会发现发现无法安全地"读取"(同时调用const
成员函数)的类会让人感到困惑.
一种选择是提供两种变体 - 使用内部存储的RNG的非const版本,以及const
通过非const引用接受RNG 的版本.(第一个可以调用第二个,const_cast
不需要).这实现了"仅根据需要付费"指导线程安全性,因为如果每个线程都提供线程本地RNG实例,则多个线程可以安全地使用该对象.它还允许使用模拟RNG实现进行测试,这可能更有价值.
这取决于你想要达到的目标,典型的策略包括:
揭露可变性.只是不要将方法标记为const
.
外化以暴露可变性.将可变元素(这里是生成器和分布)作为方法参数传递,暴露内部使用可变性,调用者负责任何线程安全隐含.
实现"逻辑"常量.如果不考虑使用随机性破坏类的逻辑常量,则可以简单地将生成器和分布声明为mutable
; 注意线程安全的影响(如果需要,即在多线程应用程序中,使用mutable
互斥锁)
您选择哪种替代方案取决于您要实现的语义.