Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forwarding the same value to two or more functions

When using forwarding references, is it a bad idea to forward the same value to more than one function? Consider the following piece of code:

template<typename Container>
constexpr auto
front(Container&& c)
-> typename Container::value_type
{ return std::forward<Container>(c).front(); }

template<typename Container>
constexpr auto
back(Container&& c)
-> typename Container::value_type
{ return std::forward<Container>(c).back(); }

template<typename Container>
constexpr auto
get_corner(Container&& c)
{
    return do_something(front(std::forward<Container(c)),
                        back(std::forward<Container>(c));
}

If Container is an lvalue-reference, the function works just fine. However, I'm worrying about situations where rvalues are passed on to it, because the value would get invalidated once a move occurs. My doubt is: Is there a correct way to forward the container in that case, without losing the value category?

like image 442
Mário Feroldi Avatar asked Sep 04 '16 22:09

Mário Feroldi


1 Answers

In general, it is not reasonable for the same function to forward the same parameter twice. Not unless it has specific knowledge of what the receiver of that forwarded parameter will do.

Remember: the behavior of std::forward can be equivalent to the behavior of std::move, depending on what parameter the user passed in. And the behavior of an xvalue will be contingent on how the receiving function processes it. If the receiver takes a non-const rvalue reference, it will likely move from that value if possible. That would leave you holding a moved-from object. If it takes a value, it will certainly move from it if the type supports it.

So unless you have specific knowledge of the expected behavior of the operations you are using, it is not safe to forward a parameter more than once.

like image 72
Nicol Bolas Avatar answered Oct 15 '22 21:10

Nicol Bolas