Assign a value to an rvalue reference returned from function

Viewed 494
#include <utility>
template <typename Container>
decltype(auto) index(Container &&arr, int n) {
    return std::forward<Container>(arr)[n];
}

Make a function call :

#include <vector>
index(std::vector {1, 2, 3, 4, 5}, 2) = 0;

When function calling finished, the object std::vector {1, 2, 3, 4, 5} will be destroyed, assigning a value to a deallocated address would cause undefined behaviour. But the above code works well and valgrind detected nothing. Maybe the compile helps me make another invisible variable like

auto &&invisible_value {index(std::vector {1, 2, 3, 4, 5}, 2)};
invisible_value = 9;

If my guess is incorrect, I want to know why assigning a value to an rvalue reference returned from function is worked and when the temporary object index(std::vector {1, 2, 3, 4, 5}, 2) will be destroyed.

This idea originated from 《Effective Modern C++》, Item3 : Understand decltype.

2 Answers

You said "When function calling finished, the object vector {1, 2, 3, 4, 5} will be destroyed" but that is untrue. The temporary created for the function call is not deleted until the statement ends, i.e. the next line of code. Otherwise imagine how much code would break that passes c_str() of a temporary string.

invisible_value = 9; is completely legal assignment as 9 is indeed a temporary. rvalue references can be assigned with a temporary but not bound to an lvalue (for example a variable; but you can achieve this like below:

int a =10;
invisible_value=std::move(a);

https://godbolt.org/z/iTNGFr. Mode detailed explanation in this question C++ Double Address Operator? (&&).

edit:

the assignment is only legal if it is in the same scope. invisible_value in this case refers to something that was in the scope of index function and it's behavior is undefined if you have a reference to it.

Related