无法按值捕获随机引擎

时间:2018-07-31 05:56:02

标签: c++11 lambda

我有这段代码无法由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不会出现在诊断中。

有人可以解释这里发生了什么吗?

1 个答案:

答案 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);   // ******
    };