I have a function whose return type is a simple generic lambda expression. (The lambda returned by this function is eventually passed as an argument to STL algorithms like std::transform() or std::accumulate().)
When the lambda does not have an explicit return type, the compiler emits no warnings:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) {return dst + src; };
}
When the lambda has an explicit return type specified:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) -> decltype(dst) {return dst + src; };
}
both compilers emit these similar warnings:
GCC: returning reference to temporary [-Wreturn-local-addr]
MSVC: returning address of a local variable or temporary
Should this warning be heeded because it indicates a shortcoming in the approach (possible undefined behavior!) and should be refactored? or are they "noise"?
I can't determine why specifying the return type explicitly would cause the returned expression to be a "temporary" when it wouldn't be otherwise. Please explain, thanks!
EDIT (to add more context):
The desire to use auto arguments to the lambda is that src and dst might be different types (e.g. one is std::uint8_t and one is std::uint_16t), but I want the return to ALWAYS be the same type as the dst argument, regardless of the type of src.
The point is that
decltype(dst)isauto const &(where you can seeautoas a template type`, so the lambda return a reference (I repeat: a reference) to a constant object.The problem is that is a reference to
that is: a reference to a temporary value, the temporary object created from the operation
dst + src, that doesn't exist anymore when the lambda conclude the execution.A possible solution: remove
-> decltype(dst)or change it to-> decltype(dst+src), so you return a value, not a reference.Another way (require more typewriting in this case but can be prefereble in more complex cases) could be remove the reference part from the type returned from
decltype().So
or, as suggested by Jarod42, also
If the type of
dstsupport the unary operator+(returning the same type ofdst), another simple solution can beThis way,
+dstis an expression, not a variable, sodecltype(+dst)isn't a reference anymore.