montecarlo类包含lambda作为成员变量。该代码可以编译,但是会在运行时导致“段错误(核心转储)”。您能解释一下如何解决吗?

#include<random>
#include<functional>
#include<iostream>

class montecarlo
{
  public:
    montecarlo(double x_min, double x_max);
    std::function<double()> rand;
};

montecarlo::montecarlo(double x_min, double x_max){
  std::random_device rd;
  std::mt19937 mt(rd());
  std::uniform_real_distribution<double> rand_(x_min, x_max);
  rand = [&](){return rand_(mt);};
}

int main(){
  montecarlo x(0, 1);
  std::cout<<x.rand()<<std::endl;
}

让我感到奇怪的是,当我将构造函数的实现更改为下面的代码时,它起作用了:
montecarlo::montecarlo(double x_min, double x_max){
  rand = [](){return 0;};
}

您可能会知道,但是让我说我​​想做的不只是使用随机函数。

最佳答案

您正在尝试通过引用捕获rand_mt;它们是montecarlo::montecarlo内部的本地对象,当在montecarlo::montecarlo外部调用lambda时,这些本地对象已被破坏,并且存储在lambda对象中的引用已悬空。

您可以将其更改为通过副本捕获。并注意您需要使lambda mutable生效,以使对rand_的调用有效。例如

rand = [=]() mutable {return rand_(mt);};

09-09 18:52