微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 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的可设置成员的功能是什么?

class MyClass
{
    public:
        inline double f(double x)
        {
            return _function(x);
        }
    // What are the setter and the type of the protected member _function ?
};

解决方法

可以使用在< functional>中找到的 std::function模板类来包装和存储Lambda函数(以及一些其他类型的“可调用函数).头.其模板参数是具有语法的函数签名
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值))的仿函数分配给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 };

为了避免这种丑陋的句法开销,添加一个利用模板类型推导的“制造商”功能

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

原文地址:https://www.jb51.cc/c/114945.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐