Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用绑定与使用带有随机数生成器的指针_C++_C++11 - Fatal编程技术网

C++ 使用绑定与使用带有随机数生成器的指针

C++ 使用绑定与使用带有随机数生成器的指针,c++,c++11,C++,C++11,我的代码中有以下实现: // first solution //random.h class Random{ public: std::mt19937* gen; std::uniform_real_distribution<double>* dis; } //random.cpp Random::Random() { std::mt19937_64::result_type seed = chrono::high_resolution_c

我的代码中有以下实现:

 // first solution 
 //random.h
class Random{
public:
    std::mt19937* gen;
    std::uniform_real_distribution<double>* dis; 
}
//random.cpp
Random::Random()
  {
        std::mt19937_64::result_type seed = chrono::high_resolution_clock::now().time_since_epoch().count();
        gen = new std::mt19937(seed);
        dis = new std::uniform_real_distribution<double>(0.0,1.0);
  }
double Random::next()
  {
        double rand  = 0;
        rand_int = (*dis)(*gen);
        return rand;
  }
考虑到您应该只有一个PRNG对象,并且您应该为它设定一次种子,然后每次需要新的随机数时都调用该对象,因为种子用于在PRNG中创建一系列随机数。我可以清楚地看到,第一种解决方案就是这样。
问题是,
bind()
在幕后是如何工作的?是不是每次调用都会创建一个新对象?它真的是调用
(构造函数)
还是调用
函数()
?它怎么知道该打哪一个?解决方案之间有什么不同吗?

std::bind
生成一个函数对象,该对象封装了提供给它的参数。实际上,您同事的代码会生成以下对象:

struct random_call
{
  random_call(unsigned seed)
  : _mt19937_64(seed)
  , _uniform_real(0.0, 1.0)
  {}

  double operator() {
    return _uniform_real(_mt19937_64);
  }

  std::mt19937_64 _mt19937_64;
  std::uniform_real_distribution<double> _uniform_real;
};
struct随机调用
{
随机_调用(未签名种子)
:_mt19937_64(种子)
,统一实数(0.0,1.0)
{}
双运算符(){
返回统一实数(_mt19937_64);
}
标准:mt19937_64_mt19937_64;
标准:均匀实分布均匀实分布;
};
所以在我看来,它看起来还不错(实际上相当聪明)


一个警告是,您可能不想复制binder对象-即使它是可复制的,复制它,然后对原始对象调用
operator()
,副本将产生相同的数字。

std::bind
生成一个封装提供给它的参数的函数对象。实际上,您同事的代码会生成以下对象:

struct random_call
{
  random_call(unsigned seed)
  : _mt19937_64(seed)
  , _uniform_real(0.0, 1.0)
  {}

  double operator() {
    return _uniform_real(_mt19937_64);
  }

  std::mt19937_64 _mt19937_64;
  std::uniform_real_distribution<double> _uniform_real;
};
struct随机调用
{
随机_调用(未签名种子)
:_mt19937_64(种子)
,统一实数(0.0,1.0)
{}
双运算符(){
返回统一实数(_mt19937_64);
}
标准:mt19937_64_mt19937_64;
标准:均匀实分布均匀实分布;
};
所以在我看来,它看起来还不错(实际上相当聪明)


一个警告是,您可能不想复制活页夹对象-即使它是可复制的,复制它,然后对原始对象调用
operator()
,副本将产生相同的数字。

古老的格言“您应该只有一个PRNG对象”谢天谢地,随着C++11随机数库的出现,它消失了。@Bathsheba,你能详细说明一下吗?参考?古老的格言“你应该只有一个PRNG对象”谢天谢地随着C++11随机数库的出现而消失了。@Bathsheba你能详细解释一下吗?参考资料?@BinaryA肯定有。你不必为解除分配(在指针上调用
delete
)和所有所有权之类的事情而烦恼,而且你还保存了一级间接寻址。指针是邪恶的,因为它们需要内存分配、生命周期管理,而且每次使用都需要取消引用。C++不是C语言。如果可以的话,请始终选择“对象是一个值”而不是“指向对象的指针”。@RichardHodges:顺便说一句,第一个解决方案可能没有指针,所以主要区别在于公开
std::function
与公开
。这是一个合理的观点,但如果是关于隐藏实现细节,那么简单的pimpl就可以做到这一点,而且根本不需要任何std::headers?@BinaryA肯定有。你不必为解除分配(在指针上调用
delete
)和所有所有权之类的事情而烦恼,而且你还保存了一级间接寻址。指针是邪恶的,因为它们需要内存分配、生命周期管理,而且每次使用都需要取消引用。C++不是C语言。如果可以的话,请始终选择“对象是一个值”而不是“指向对象的指针”。@RichardHodges:顺便说一句,第一个解决方案可能没有指针,所以主要区别在于公开
std::function
与公开
。这是一个合理的观点,但如果是关于隐藏实现细节,那么简单的pimpl就可以做到这一点,而且根本不需要任何std::header?