我有这段代码无法由gcc 8编译,但我不明白为什么。
#include <iostream>
#include <algorithm>
#include <random>
using namespace std;
template<class... T>
void diagnose(T... x);
int main()
{
auto d = normal_distribution<double>(0.0, 1.0);
auto g = default_random_engine();
cout << d(g) << endl;
auto gen = [=](){
//diagnose(d, g);
return d(g); // ******
};
cout << gen() << endl;
}
错误消息显示(指向由*******
标记的行):
error: no match for call to ‘(const std::normal_distribution<double>) (const std::linear_congruential_engine<long unsigned int, 16807, 0, 2147483647>&)
但是,如果我将捕获更改为通过引用进行操作,该代码将起作用。
如果我取消注释//diagnose
行的注释,则错误消息是这样的(也需要将return d(g)
更改为return 1.0
):
undefined reference to `void diagnose<std::normal_distribution<double>, std::linear_congruential_engine<unsigned long, 16807ul, 0ul, 2147483647ul> >(std::normal_distribution<double>, std::linear_congruential_engine<unsigned long, 16807ul, 0ul, 2147483647ul>)'
如您所见,在按值捕获的情况下,参数g
是const引用。但是const
不会出现在诊断中。
有人可以解释这里发生了什么吗?
答案 0 :(得分:3)
您通过值d
传递了[=]
,因此该对象的副本在lambda内创建,但是lambda函数的主体为const
,因此您无法在lambda主体内更改对象。 normal_distribution::operator()
成员不是const。在const成员中,您只能为成员对象调用const方法。您可以通过向lambda添加mutable来解决该问题
auto gen = [=]() mutable {
//diagnose(d, g);
return d(g); // ******
};
或通过引用传递d
auto gen = [&](){
//diagnose(d, g);
return d(g); // ******
};