C++:从捕获函数参数的函数返回 lambda 表达式
C++: Return a lambda expression from a function that captures parameter of the function
下面的函数应该获取多项式的系数并从中创建时间函数:
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::vector<double> coefficients = {1.0,2.0,3.0};
auto f = to_equation(coefficients);
auto value = f(t);
然而,代码并没有按预期工作,因为在执行f(t)
时,不是使用传递给to_equation(coefficients)
的系数,而是从上下文中神奇地捕获了一些完全不同的值。发生了什么,我该如何解决?
好吧,您返回的 lambda 按值捕获coefficients
。如果将某个向量传递给to_equation
函数,则将复制所有值,并且 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::function<double(double)> f;
{
std::vector<double> coeff{0.2, 0.4, 9.8};
f = to_equation(coeff);
}
auto result = f(3);
这很糟糕,载体coeff
寿命不够长,我们在载体被破坏后再引用它。
我建议将此重载添加到您的函数中:
// 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
您可以按引用而不是按值捕获。但是,当然,如果底层向量超出范围并在调用 lambda 之前被销毁,那么您手上就会一团糟。
最安全的做法是使用std::shared_ptr<std::vector<double>>
而不是普通向量,并按值捕获它。然后,lambda 本质上将始终以最新的系数集为食,如果在对底层向量的所有其他引用(从计算它们的任何代码(超出范围之后调用它,则不会爆炸。
(当然,你必须记住,如果 lambda 被复制,这里会发生什么,因为原始 lambda 的所有副本都将使用相同的向量(。
有关更多信息,请打开C++书中的章节,其中解释了使用 lambda 时按值捕获和按引用捕获之间的区别。
相关文章:
- 从函数返回const char*数组
- 检查函数返回类型是否与STL容器类型值相同
- 从 c 或 cpp 系列子函数返回到主函数
- 从函数返回任意简单类型的数据
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 从 C++ 中的函数返回数组地址问题
- VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0
- 为什么glGetSubroutineIndex为不同的函数返回相同的值?
- 在 c++ 中将函数返回类型指定为模板参数
- 从封装在对象中的函数 C++ 返回时为空的列表
- 为什么向量内部的指针在从函数返回时会发生变化?
- 函数返回的 rvalue 引用(表达式)是 xvalue - 但没有标识?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 寿命延长从函数返回引用
- 程序不向函数返回值
- 字符串函数返回奇怪的值
- 类的大问题,以及从空函数c++返回
- 为什么在尝试测量函数返回所需的时间时,我的运行时编号是错误的?
- C++二叉搜索树模板从函数返回节点
- NVCC 错误:string_view.h:constexpr 函数返回是非常量