【问题标题】:Is there a documented way to reset the lambda parameter on an existing std::exponential_distribution object?是否有记录的方法来重置现有 std::exponential_distribution 对象上的 lambda 参数?
【发布时间】:2017-08-28 22:42:53
【问题描述】:

当我查看std::exponential_distribution 的文档时,它似乎没有公开在运行时更改 lambda 参数的标准方法。

有一个param 方法,但它采用不透明的成员类型param_type,并且获得这种类型对象的唯一记录方法是不带参数调用param,但这意味着不同必须首先使用该参数创建实例。

下面,我展示了两种未记录的重置 lambda 编译的方法,但我不知道它们是否会在运行时产生正确的行为。

#include <random>
#include <new>

int main(){
    std::random_device rd;
    std::mt19937 gen(rd());
    std::exponential_distribution<double> intervalGenerator(5);

    // How do we change lambda after creation?
    // Construct a param_type using an undocumented constructor?
    intervalGenerator.param(std::exponential_distribution<double>::param_type(7));

    // Destroy and recreate the distribution?
    intervalGenerator.~exponential_distribution();
    new (&intervalGenerator) std::exponential_distribution<double>(9);
}

是否有记录的方法可以做到这一点,如果没有,这两种解决方案中的任何一种都可以安全使用吗?

【问题讨论】:

  • 这不是无证的。 param_type 始终可以使用与父分布相同的参数构造。
  • @Praetorian,是否有关于其构造函数的文档?我找不到任何东西。
  • param_type 可以使用与其分布相同的参数构造这一事实是RandomNumberDistribution 概念 (26.5.1.6/9) 的要求之一。

标签: c++ c++11 exponential-distribution


【解决方案1】:

只需为旧实例分配一个新生成器:

std::exponential_distribution<double> intervalGenerator(5);
intervalGenerator = std::exponential_distribution<double>(7);

便携、易读且明显正确。


还有,

intervalGenerator.param(std::exponential_distribution<double>::param_type(7));

在 N3337 和 N4141 中如 26.5.1.6/9 中所述是安全的,因此您也可以使用它。但是对于第一个变体,一开始就不会出现可移植性问题。

【讨论】:

  • 我正在努力减少此更改的开销,并且我担心为额外的对象付费。似乎很傻,必须丢弃对象并创建一个全新的对象只是为了重置一个参数。
  • @merlin2011 不会有任何开销。不要再浪费时间猜测性能了,在实际发现问题后进行优化。
  • @Fanael,公平点。也许我多虑了。 :P 将在计时器到期时接受。
  • @Fanael 即使在-O1 也可以使用。这是编译器的简单优化
  • @Justin:即使在 -Og 也能工作。我只是使用-O3 作为默认值。
猜你喜欢
  • 2016-01-25
  • 2016-01-25
  • 2010-09-15
  • 1970-01-01
  • 2013-03-02
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
相关资源
最近更新 更多