std :: functions和lambda函数传递

Moc*_*han 4 c++ lambda c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

呼叫t.F()导致故障.为什么?

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

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

    t.F();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但同样,这并不当我改变工作fnauto!

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

    t.F();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

son*_*yao 5

注意,(1)fn被定义为引用(对于const); (2)lambda和std::function不同的类型; (3)您不能直接绑定对不同类型的对象的引用.

对于第一种情况,

TestClass t([](std::string str) {std::cout << str << std::endl; });
t.F();
Run Code Online (Sandbox Code Playgroud)

创建临时lambda然后转换为临时lambda std::function.临时std::function绑定到_f构造函数的参数并绑定到成员f.临时将在此声明之后被销毁,然后ft.F();失败时被悬空.

对于第二种情况,

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

创建临时lambda然后绑定到引用(到const).然后它的生命周期延长到引用的生命周期__f,所以代码很好.

对于第三种情况,

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

创建lambda然后将std::function其转换为临时的.临时std::function绑定到_f构造函数的参数并绑定到成员f.临时将在此声明之后被销毁,然后ft.F();失败时被悬空.


(1)您可以声明fn为非参考typedef std::function<void(std::string)> fn;,然后std::function将被复制,每个案例都可以正常工作.
(2)不要使用以双下划线开头的名称,它们是在C++中保留的.