Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign a value to an rvalue reference returned from function

#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.

like image 739
Jonny0201 Avatar asked Jun 03 '20 05:06

Jonny0201


People also ask

Can a function return an rvalue?

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.

Can lvalue bind to rvalue reference?

An lvalue reference can bind to an lvalue, but not to an rvalue.

How do I create an rvalue reference?

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.

Can you take the address of 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.

What is an R-value reference in C++?

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.

What is the use of L-value and R-value?

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.

Can you pass an object to a function that takes rvalue?

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.

What is the difference between R value and l value?

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.


1 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.

like image 71
Patrick Parker Avatar answered Oct 19 '22 18:10

Patrick Parker