c++ - lambda 函数的 setter ?

标签 c++ c++11 lambda setter

考虑以下愚蠢的例子:

class MyClass
{
    public:
        template <class Function> 
        inline double f(double x, Function&& function)
        {
            return function(x);
        }
};

有了这个类,我可以调用 MyClass::f(x, function),使用 lambda 函数在 x 上执行它,(我希望)没有高架。我的问题是:作为 MyClass 的可设置成员,function 有什么等价物?

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> 中找到 header 。它的模板参数是一个函数签名,其语法为

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);

关于c++ - lambda 函数的 setter ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16667452/

相关文章:

c++ - 值初始化一个自动对象?

c++ - FILE_ATTRIBUTE_NORMAL 和 0 有什么区别?

c++ - 返回 const std::string 真的比非 const 慢吗?

javascript - 如何将此 javascript 代码重写为 C++11?

java - 将列表转换为 map

Java List<Map<String, Long>> 映射键的分组总和

c++ - 我应该怎么做才能获得用户输入的最小序列?

c++ - 在 C++ 中删除指针

c++ - 为什么 std::map< std::map > 不释放内存?

java - 使用流读取文本文件 - lambda 表达式中的变量