Setter of a lambda function?
Setter of a lambda function?
考虑以下愚蠢的例子:
class MyClass
{
public:
template <class Function>
inline double f(double x, Function&& function)
{
return function(x);
}
};
有了这个类,我可以调用MyClass::f(x, function)
,用lambda函数在x
上执行它,(我希望)没有开销。我的问题是:function
作为MyClass
的可设置成员的等效是什么?
class MyClass
{
public:
inline double f(double x)
{
return _function(x);
}
// What are the setter and the type of the protected member _function ?
};
Lambda函数(以及一些其他类型的"可调用"函数)可以使用std::function
模板类包装和存储,在<functional>
头文件中找到。它的模板形参是一个函数签名,语法为
ReturnType(ArgumentType1, ArgumentType2, ...)
所以在你的例子中,整个函数包装器类型变成
std::function<double(double)>
,因此,你的代码变成
class MyClass
{
public:
inline double f(double x)
{
return _function(x);
}
void setFunction(std::function<double(double)> && f)
{
_function = f;
}
private:
std::function<double(double)> _function;
};
std::function
"不仅仅"是函数指针的包装器。您可能知道,lambda函数可以捕获变量上下文的一部分,这些上下文需要存储在某个地方。std::function
为您透明地完成此操作。
注意std::function
不支持函数的重载签名/模板化调用操作符。当将具有调用操作符签名(如T operator()(T value)
)的函子赋值给std::function<double(double)>
时,只能使用此签名调用该函子。所以没有std::function<T(T)>
(除非T
是已知的,比如你的类的模板参数)。
在某些情况下(您需要对其进行基准测试/配置文件),另一种可能更有效的方法是使整个类成为模板类,并将函数类型参数作为模板参数。然后可以将函数存储为成员:
template<typename Function>
class MyClass
{
public:
MyClass(Function && f) :
_function(f)
{}
inline double f(double x)
{
return _function(x);
}
private:
Function _function;
};
为了创建这样一个对象,需要指定模板参数,如下所示:
auto myLambda = [](double x){ return x * 0.25; };
MyClass<decltype(myLambda)> myObject { myLambda };
为了避免这种难看的语法开销,添加一个利用模板类型推导的"maker"函数:
template<typename Function>
auto makeMyClass(Function && f) -> MyClass<Function> {
return MyClass<Function>(f);
}
然后,再次使用auto
,代码变得更可读:
auto myLambda = [](double x){ return x * 0.25; };
auto myObject = makeMyClass(myLambda);
您必须使用std::function
包装器,可能让构造函数从输入可调用对象初始化它:
#include <functional> // <== REQUIRED FOR std::function
class MyClass
{
public:
template<typename F>
MyClass(F&& f) : _function(std::forward<F>(f)) { }
inline double f(double x)
{
return _function(x);
}
private:
std::function<double(double)> _function;
};
注意,这可能会给您带来一些运行时开销,但是设计是简单而灵活的。除非您能够证明此运行时开销是软件性能需求的瓶颈,否则不应该关注此运行时开销。
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 将 lambda 表达式传递给 std::function in C++
- 从 std::function in C++ 访问模板化 lambda
- 如果 lambda 没有指定的类型,std::function 如何接受 lambda?
- 针对 std::function 的 lambda 表达式和模板推导:为什么会这样?
- std::function<std::optional<T>()> 如何与返回 T 的 lambda 兼容?
- 可以将模板化的 lambda 存储到 std::function 中吗?
- Visual Studio 2017中的哪些扩展在传入lambda时消除了"bool"与"std::function"的歧义?
- 使用 std::function 调用函数作为带有 lambda 的参数
- 使用 lambda/std::function 删除拥有该函数的对象
- std::function std::bind with lambda overload ambiguity
- c++ goto vs std::function lambda?
- 将 lambda 传递给 STL 集时出错"bad function call"
- Lambda 捕获'this'另存为 std::function
- lambda 和 std::function 的包装器
- 将 lambda 推导为 std::function<T>
- const std::function 包装一个非 const 运算符() / 可变 lambda
- 如果我使用 std::function 来捕获 lambda,我应该担心它被解除分配吗?
- 透明地配置std::function / lambda回调