c++ - std::functions and lambda function passing -
i have class takes std::function
parameter assign lambda function. works in constructor stops working after that. debugger says f
"empty" after running first line. why?
#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; }
calling t.f()
causes fault. why?
i can solve changing following:
int main() { fn __f = [](std::string str) {std::cout << str << std::endl; }; testclass t(__f); t.f(); return 0; }
but again, not work when change fn
auto
!
int main() { auto __f = [](std::string str) {std::cout << str << std::endl; }; testclass t(__f); t.f(); return 0; }
what explanation of why happening?
note (1) fn
defined reference (to const); (2) lambda , std::function
not same type; (3) can't bind reference object different type directly.
for 1st case,
testclass t([](std::string str) {std::cout << str << std::endl; }); t.f();
a temporary lambda created , converted std::function
temporary too. temporary std::function
bound parameter _f
of constructor , bound member f
. temporary destroyed after statement, f
becomes dangled, when t.f();
fails.
for 2nd case,
fn __f = [](std::string str) {std::cout << str << std::endl; }; testclass t(__f); t.f();
a temporary lambda created , bound reference (to const). lifetime extended lifetime of reference __f
, code fine.
for 3rd case,
auto __f = [](std::string str) {std::cout << str << std::endl; }; testclass t(__f); t.f();
lambda created , converted std::function
temporary. temporary std::function
bound parameter _f
of constructor , bound member f
. temporary destroyed after statement, f
becomes dangled, when t.f();
fails.
(1) declare fn
non-reference typedef std::function<void(std::string)> fn;
, std::function
copied , every case work well.
(2) don't use names begin double underscore, they're reserved in c++.
Comments
Post a Comment