c++ - std::functions 和 lambda 函数传递

标签 c++ c++11 lambda std-function

我有一个将 std::function 作为参数的类,我分配了一个 lambda 函数。它在构造函数中工作,但之后停止工作。调试器在运行第一行后说 f 是“空的”。为什么?

#include <iostream>
#include <string>
#include <functional>

typedef std::function<void(std::string)> const& fn;

class TestClass
{
public:
    TestClass(fn _f) : f(_f) { F(); }
    void F() { f("hello"); };

private:
    fn f;
};


int main()
{
    TestClass t([](std::string str) {std::cout << str << std::endl; });

    t.F();

    return 0;
}

调用 t.F() 会导致错误。为什么?

我可以通过将其更改为以下内容来解决它:

int main()
{
    fn __f = [](std::string str) {std::cout << str << std::endl; };
    TestClass t(__f);

    t.F();

    return 0;
}

但是,当我将 fn 更改为 auto 时,这同样不起作用!

int main()
{
    auto __f = [](std::string str) {std::cout << str << std::endl; };
    TestClass t(__f);

    t.F();

    return 0;
}

发生这种情况的原因是什么?

最佳答案

请注意 (1) fn被定义为引用(对 const); (2) λ 和 std::function不是同一类型; (3) 不能直接将引用绑定(bind)到不同类型的对象。

对于第一种情况,

TestClass t([](std::string str) {std::cout << str << std::endl; });
t.F();

创建临时 lambda,然后将其转换为 std::function这也是暂时的。临时std::function绑定(bind)到参数 _f构造函数并绑定(bind)到成员 f .这条语句后临时文件将被销毁,然后ft.F(); 时变得悬空它失败了。

对于第二种情况,

fn __f = [](std::string str) {std::cout << str << std::endl; };
TestClass t(__f);
t.F();

创建了一个临时的 lambda,然后将其绑定(bind)到引用(到 const)。然后它的生命周期被延长到引用的生命周期 __f , 所以代码没问题。

对于第三种情况,

auto __f = [](std::string str) {std::cout << str << std::endl; };
TestClass t(__f);
t.F();

创建 lambda 然后转换为 std::function这是一个临时的。临时std::function绑定(bind)到参数 _f构造函数并绑定(bind)到成员 f .这条语句后临时文件将被销毁,然后ft.F(); 时变得悬空它失败了。


<支持> (1) 你可以声明 fn作为非引用,如 typedef std::function<void(std::string)> fn; , 然后 std::function将被复制,每个案例都会运作良好。
(2) 不要使用双下划线开头的名称,它们在 C++ 中是保留的。

关于c++ - std::functions 和 lambda 函数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38831661/

相关文章:

c++ - 为什么我们需要 C++ 中的纯虚析构函数?

c++ - CRTP编译错误

java - 如何避免在包装类中重复复杂的异常处理代码?

c# - 从一组枚举值中选择

c++ - 读取文件头

c++ - 在 GDB 中调用 lambda 函数

c++ - 线程 : Does starting location makes a difference

c++ - Boost foreach 与 Q_FOREACH (Qt) 和 moc 生成冲突?

c++ - 为什么 glDrawArrays 不能在 mac 上使用 OpenGL 绘制

c++ - 为什么允许没有名字的声明?