以下代码可以正常使用
#include <iostream>
#include <random>
int main() {
std::default_random_engine generator;
std::normal_distribution<double> distribution(5.0, 2.0);
std::vector<double> v(100);
std::generate(v.begin(), v.end(), [&] () { return distribution(generator); });
return 0;
}
但是,将lambda的捕获列表更改为[=]
或[&, distribution]
或[&, generator]
会导致
rand.cpp:9:59: error: no matching function for call to object of type 'const std::normal_distribution<double>'
error: assigning to 'double' from incompatible type 'void'
在lambda中是否有某些类型的对象无法通过值捕获?
答案 0 :(得分:4)
看起来std::normal_distribution<double>::operator()
不是const
。
所以你必须在lambda中添加mutable
关键字:
std::generate(v.begin(), v.end(), [=] () mutable {
return distribution(generator);
});
std::generate(v.begin(), v.end(), [&, distribution] () mutable {
return distribution(generator);
});
这两种方法都很好。
答案 1 :(得分:4)
通常,按值捕获需要对象可复制。 std::default_random_generator
和std::normal_distribution
都是可复制的,因此这不应该是一个问题。
Lambda captures are always const values or const references.随机数生成本质上是有状态的,因此被调用的operator()
不能是const,因为它可能会修改对象状态。错误消息通过声明在const std::normal_distribution<double>
上没有调用函数来加密地报告这一点。
如果要修改捕获的对象,则必须将lambda声明为可变
#include <iostream>
#include <random>
#include <algorithm>
int main() {
std::default_random_engine generator;
std::normal_distribution<double> distribution(5.0, 2.0);
std::vector<double> v(100);
std::generate(v.begin(), v.end(), [generator, distribution] () mutable { return distribution(generator); });
return 0;
}