C++ C++;:从捕获函数参数的函数返回lambda表达式

C++ C++;:从捕获函数参数的函数返回lambda表达式,c++,lambda,c++14,C++,Lambda,C++14,假设以下函数取多项式的系数,并从中创建时间函数: std::function<double(double)> to_equation(const std::vector<double>& coefficients) { return [coefficients](double t) { auto total = 0.0; for (int i = 0; i < coefficients.size(); i++)

假设以下函数取多项式的系数,并从中创建时间函数:

std::function<double(double)> to_equation(const std::vector<double>& coefficients)
{
    return [coefficients](double t)
    {
        auto total = 0.0;
        for (int i = 0; i < coefficients.size(); i++)
        {
            total += coefficients[i] * pow(t,i);
            return total;
        }
    };
}
std::函数到方程(常数std::向量和系数)
{
返回[系数](双t)
{
自动总计=0.0;
对于(int i=0;i
其可用性应如下所示:

std::vector<double> coefficients = {1.0,2.0,3.0};
auto f = to_equation(coefficients);
auto value = f(t);
std::向量系数={1.0,2.0,3.0};
auto f=to_方程(系数);
自动值=f(t);

然而,代码并没有按预期工作,因为在执行
f(t)
时,并没有使用传递到
to_方程(系数)
的系数,而是从上下文神奇地捕获了一些完全不同的值。发生了什么,我如何解决

您可以通过引用而不是通过值进行捕获。但是,当然,如果基础向量超出范围并在lambda被调用之前被破坏,那么您将面临一个大麻烦

最安全的做法是使用
std::shared_ptr
而不是普通向量,并通过值捕获该向量。然后,lambda将始终,本质上,以最新的一组系数为基础,并且如果在所有其他对基础向量的引用(从任何代码计算它们)超出范围后调用它,它将不会爆炸

(当然,您必须记住,如果lambda被复制,这里会发生什么,因为原始lambda的所有副本都将使用相同的向量)


<> P>更多信息,打开C++书的章节,解释使用lambDas时,按值捕获和引用的区别。

,您返回的是一个捕获值<>代码>系数值的lambda。如果将某个向量传递给

to_等式
函数,所有值都将被复制,lambda将不再引用原始向量

我建议这个解决方案:

// auto is faster than std::function
auto to_equation(const std::vector<double>& coefficients)
{
    // Here, you capture by reference.
    // The lambda will use the vector passed in coefficients
    return [&coefficients](double t)
    {
        // ...
    };
}
然后,可以通过两种方式调用函数:

std::vector<double> coeff{0.2, 0.4, 9.8};

auto f1 = to_equation(coeff); // uses reference to coeff
auto f2 = to_equation({0.2, 0.4, 9.8}) // uses value moved into the lambda
std::向量系数{0.2,0.4,9.8};
自动f1=到_方程(系数);//使用对系数的引用
auto f2=to_方程({0.2,0.4,9.8})//使用移动到lambda中的值
// when a vector is moved into coefficients, move it to the lambda
auto to_equation(std::vector<double>&& coefficients)
{
    // Here, you capture by value.
    // The lambda will use it's own copy.
    return [coeff = std::move(coefficients)](double t)
    {
        // ...
    };
}
std::vector<double> coeff{0.2, 0.4, 9.8};

auto f1 = to_equation(coeff); // uses reference to coeff
auto f2 = to_equation({0.2, 0.4, 9.8}) // uses value moved into the lambda