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)
但同样,这并不当我改变工作fn来auto!
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)
为什么会发生这种情况的原因是什么?
注意,(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.临时将在此声明之后被销毁,然后f在t.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.临时将在此声明之后被销毁,然后f在t.F();失败时被悬空.
(1)您可以声明fn为非参考typedef std::function<void(std::string)> fn;,然后std::function将被复制,每个案例都可以正常工作.
(2)不要使用以双下划线开头的名称,它们是在C++中保留的.