#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
.
Typically rvalues are temporary objects that exist on the stack as the result of a function call or other operation. Returning a value from a function will turn that value into an rvalue. Once you call return on an object, the name of the object does not exist anymore (it goes out of scope), so it becomes an rvalue.
An lvalue reference can bind to an lvalue, but not to an rvalue.
An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.
2) non-modifiable lvalues, which are const. rvalue — The expression that refers to a disposable temporary object so they can't be manipulated at the place they are created and are soon to be destroyed. An address can not be taken of rvalues. An rvalue has no name as its a temporary value.
L-value references to const objects are particularly useful because they allow us to pass any type of argument (l-value or r-value) into a function without making a copy of the argument. C++11 adds a new type of reference called an r-value reference.
R-value references are more often used as function parameters. This is most useful for function overloads when you want to have different behavior for l-value and r-value arguments. As you can see, when passed an l-value, the overloaded function resolved to the version with the l-value reference.
You can pass an object to a function that takes an rvalue reference unless the object is marked as const. The following example shows the function f, which is overloaded to take an lvalue reference and an rvalue reference.
An r-value reference is a reference that is designed to be initialized with an r-value (only). While an l-value reference is created using a single ampersand, an r-value reference is created using a double ampersand: R-values references cannot be initialized with l-values.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With