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