如何用lambda传递对函数的引用

How to pass reference to function with lambda

本文关键字:函数 引用 何用 lambda      更新时间:2023-10-16

我有一个类型为:

的数据成员
std::function<T(T&, T&)>&

构造函数接受相同类型的实参。

我应该如何使用lambda发送这样的函数?

我试过了

MyClass tmp([](Foo &a, Foo &b) { return a+b; }, ...);

但是失败了。

例如:

main.cpp

#include "MyClass.h"
int main()
{
    MyClass a([](int x, int y) { return x+y;});
    return 0;
}

MyClass.h

#pragma once
#include <functional>
class MyClass
{
    public:
        MyClass(std::function<int(int, int)>&) noexcept;
    private:
        std::function<int(int, int)>& fun;
};

您正在将lambda传递给std::function &。A不是std::function,所以它不能直接工作。但是,lambda可以转换为std::function,因此必须构建一个临时的std::function来保存lambda。

因为你接受的是std::function &, c++假设你想修改这个值,否则通过非const引用接受它就没有意义了。修改临时对象没有效果,所以这没有意义,所以c++不允许这样做。

解决这个问题的一种方法是采取const std::function &。这样就不需要修改临时文件。

另一种方法是传递您在main中创建的实际std::function

另一种方法是创建一个模板,将它的参数转发给std::function:

class MyClass
{
    public:
        template <class T>
        MyClass(T &&t)
            : fun(std::forward<T>(t)){}
    private:
        std::function<int(int, int)> fun;
};

这样MyClass就可以取任意值来构造fun。注意,fun不再是一个引用。std::function必须存在于某个地方,并且由于它是MyClass的一部分,因此将std::function的生命周期与MyClass联系起来是有意义的。

如果你真的想让fun成为一个引用,你需要为它找到一个地方,并确保它留在那里,直到MyClass a;被销毁。我不推荐使用这种方法,因为确保生命周期正确变得越来越困难。

您也可以直接存储lambda,但这有点棘手,并且取决于您实际想要对MyClass做什么,它可能不可行。