I am struggling with miniproject, where I have to do this
const Foo &f = func(arr(1.3, 2.4, 3.8, 4.3));
Foo
is non-duplicable class containing single float
value as memeber, arr
is simple function that returns std::vector
of Foo
objects initialized with values passed as parameter into arr
. Finally func
is defined as following:
const Foo &func(const std::vector<Foo> &in)
{
return *std::max_element(in.begin(), in.end());
}
Foo
has defined operator<
function, that determines which of the two Foo
s have bigger value, thus std::max_element
works as should. Foo
has also defined Foo(Foo &&v)
that copies value.
I know that parameter of func
is created as temporary.
Application is compilable, but after debugging, the object f
contains some random value, that is not even in passed array (since the object was already destroyed?).
Is there any possible way to change func
so this will work?
Since the result of func
is a reference to an element of the vector
passed to it, then you must ensure that the vector
argument is still alive when you access the result. Passing a temporary object ( arr(1.3, 2.4, 3.8, 4.3)
) means that vector will be destroyed as soon as func
is evaluated and thus the reference returned is no good. Call func
without a temporary vector parameter and you should be fine:
auto func_arg = arr(1.3, 2.4, 3.8, 4.3);
const Foo &f = func(func_arg);
There's nothing you can change within func
to make the returned reference valid. The input must be a non-temporary.
If func
were to return by value, it would return a temporary object whose lifetime would be extended to that of f
.
However, the object needs to be moved from the input array since it cannot be copied. This is a problem because the input parameter is a const
reference. So provide an overload that takes a movable parameter that can bind to a temporary vector. This could be either receiving by value or taking a non- const
r-value reference.
Foo func(std::vector<Foo> && in)
// ^ ^----------------^^------- non-const r-vlaue reference
// |------------------------------- return a temporary, not a reference
{
return std::move(*std::max_element(in.begin(), in.end()));
// ^^^^^^^^^--------------------- move the result
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.