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 seeauto
as 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
dst
support the unary operator+
(returning the same type ofdst
), another simple solution can beThis way,
+dst
is an expression, not a variable, sodecltype(+dst)
isn't a reference anymore.