The for(:) loop range initialization line does not extend the life of anything other than the last temporary (if any). Any other temporary files are discarded before the for(:) loop is executed.
Now, do not despair; There is an easy solution to this problem. But first go through what goes wrong.
The for(auto x:exp){ /* code */ } expands, mainly:
{ auto&& __range=exp; auto __it=std::begin(__range); auto __end=std::end(__range); for(; __it!=__end;++__it){ auto x=*__it; } }
(With a modest lie on the lines __it and __end , and all variables starting with __ do not have a visible name. I also show the version in C ++ 17 because I believe in a better world, and the differences do not matter here.)
Your exp creates a temporary object and then returns a link inside it. Temporary dies after this line, so in the rest of the code you have a dangling link.
Fixation is relatively simple. To fix this:
std::string const& func() const& // notice & { return m.find("key")->second; } std::string func() && // notice && { return std::move(m.find("key")->second); }
do rvalue overloads and return moved values ββby value when using temporary times, instead of returning references to them.
Then
auto&& __range=exp;
Line
refers to the extension of the life cycle to the return value of string and no longer wraps links.
As a rule, never return a range by reference to a parameter, which may be the value of r.
Appendix: Wait, && and const& after methods? rvalue links to *this ?
C ++ 11 added rvalue links. But this or self function is special for functions. To select which method overload is based on the rvalue / lvalue-ness of the called object, you can use & or && after the method finishes.
This works the same as the parameter type for a function. && after the method states that the method should only be called on non-constant values; const& means that it must be called for constant lvalues. Things that do not exactly match correspond to the usual rules of compliance.
When you have a method that returns a link to an object, make sure that you catch temporary files with the && overload and either do not return the link in these cases (return a value) or the =delete method.