stl c ++ 11解决方案:
auto distribution = std::bind(std::normal_distribution<double>{mean, stddev},
std::mt19937(std::random_device{}())
);
std::transform(data.begin(), data.end(), data.begin(),
std::bind(std::plus<double>(), std::placeholders::_1, distribution()));
基于范围的简单循环:
for (auto& d : data) {
d += distribution();
}
我的STL解决方案不起作用,因为它始终采用从分发中生成的第一个数字。我尝试使用占位符作为第三个参数,但它不会改变任何东西。我的所有数据都增加了相同的数字,这不是我想要的。我想要与基于范围的循环相同的行为。
这有可能吗?
答案 0 :(得分:2)
让我们将您的第二个bind
重写为lambda,以了解其实际效果如何:
auto func = std::bind(std::plus<double>(), std::placeholders::_1, distribution())
也是等同的
auto d = distribution();
auto func = [d](double x){ return std::plus<double>()(x,d); };
或者,如果我们使用C ++ 14的初始化功能:
auto func = [d=distribution()](double x){ return std::plus<double>()(x,d); };
如您所见,distribution()
只被调用一次。但是,您不想使用distribution
的返回值,要为distribution
的每次调用致电func
。虽然使用bind
可以做到这一点,但lambda会使这更容易:
std::transform(data.begin(), data.end(), data.begin(),
[&distribution](double x){ return x + distribution(); });
在我看来,这比以前的bind
更容易阅读。请注意,std::bind
(或更确切地说boost::bind
)早于lambdas。与std::bind
相比,C ++ 11中有some issues with lambdas,但对于C ++ 14,lambdas通常更容易处理,阅读和理解而不会牺牲太多。