2

(改写问题)

我正在创建一个用于提升正态分布的包装类,并希望使其尽可能高效。

如果我使用:

double x = 0.0;
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);
for (int i=0; i<20; i++) {
     double x = var_nor();
}

循环工作正常。我担心的是我不想声明任何不必要的东西,因为该方法被多次调用。我尝试拆分代码并将这一行放在构造函数中:

boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor(rng, nd);

并有一个执行此操作的示例方法:

     double x = var_nor();
     return x;

但在这种情况下,我收到一条错误消息,提示找不到 var_nor()(即没有参数)。谁能告诉我这些提升声明发生了什么,即。什么是

boost:variate_generate 等

行实际上与var_nor一起做吗?以我有限的 C++ 知识,看起来好像 var_nor 是用两个不同的签名定义的。

谢谢大家皮特

4

2 回答 2

4

在您的代码中,var_nor是一个变量,而不是一个函数,因此它没有签名。它表示一个variate_generator可以函数一样工作的对象,因为它支持operator().

在您的代码中,您同时声明和初始化var_nor。和参数被传递给对象rng构造函数。ndvariate_generator

当您将声明移到类的构造函数中时,您在构造函数中声明var_nor局部变量,因此难怪它在其他地方不可用。对于整个类中都可用的东西,它需要是一个成员变量。在类中将其声明为私有:

class NormalDistribution
{
  boost::random::mt19937 _rng;
  boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
public:
  NormalDistribution();
};

然后在构造函数中初始化它:

NormalDistribution::NormalDistribution():
  _rng(), var_nor(_rng, boost::normal_distribution<>(0.0, 1.0))
{ }

_rng需要先声明该成员,以便首先对其进行初始化。该nd参数可以省略并替换为normal_distribution直接传递给var_nor构造函数的临时对象,如上所示。

通过这些更改,您应该能够normal_distribution在多次调用您的sample函数或您的NormalDistribution类的任何其他用途时使用相同的对象。

在您从问题中删除的代码中,您将变量声明与函数声明混淆了。您声明nd为一个接收两个参数并返回一个normal_distribution. 同样与var_nor. 当你真的想要一个对象时,它是一个函数。你很困惑,因为它恰好是一个像函数一样工作的对象,但它仍然只是一个对象。

于 2012-05-31T12:34:42.820 回答
0

好的,对于可能感兴趣的其他人,使用 Rob Kennedy 的答案工作最终版本:

// normaldistribution.h
#ifndef NORMALDISTRIBUTION_H
#define NORMALDISTRIBUTION_H

#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
class NormalDistribution
{
 public:
    NormalDistribution();
    double sample(void);
 private:
    // Use the boost random number generator
    boost::mt19937 rng;
    // Make a variate_generator OBJECT.
    boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
};

#endif // NORMALDISTRIBUTION_H

// normaldistribution.cpp
NormalDistribution::NormalDistribution():
  rng(), var_nor(rng, boost::normal_distribution<>(0.0, 1.0))
{
    std::cout << "Called normal distribution constructor, passing up var_nor" << std::endl;
}

double NormalDistribution::sample(void) {
    double x = var_nor();
    return x;
}

// main.cpp
#include "normaldistribution.h"

int main(int argc, char *argv[])
{
    NormalDistribution *nd = new NormalDistribution();
    for (int i=0; i < 10; ++i)
    {
      double d = nd->sample();
      std::cout << d << std::endl;
    }
    return 0;
}
于 2012-05-31T12:53:08.163 回答