So I understand that s2
binds to the expression s1 + s1
, but is this evaluated at the time s2
is assigned or is it lazy and evaluated when s2 += "Test";
is called? And also would s2
hold memory for a temporary string?
#include <iostream>
#include <string>
int main()
{
std::string s1 = "Test";
std::string&& s2 = s1 + s1;
s2 += "Test";
std::cout << s2 << '\n';
}
An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.
An rvalue is an expression that is not an lvalue. Examples of rvalues include literals, the results of most operators, and function calls that return nonreferences. An rvalue does not necessarily have any storage associated with it.
Typically, it will be treated like an automatic variable, stored in registers or in the function's stack frame.
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.
s2
binds to the expressions1 + s1
, but is this evaluated at the times2
is assigned
Yes.
And also would
s2
hold memory for a temporary string?
Precisely, s2
is bound to a temporary std::string
.
s1 + s1
will produce a temporary std::string
, which will be bound to the reference s2
(and its lifetime is extended to the lifetime of the reference). Then s2 += "Test";
, performs operator+=()
on s2
, i.e. the temporary std::string
.
Expressions are always evaluated at the point the program reaches them. The result of an expression is always a value (or void).
Values have a type, and expressions have a value category, which combine to choose which overload of an overload set is used, at any particular use.
In your case, string operator+(...)
results in a string value, with the category pr-value (which is a type of rvalue). It is then immediately bound to a string&&, so it's lifetime is extended to that of the reference.
If you had instead assigned it to a plain string, string& string::operator=(string&&)
would have been chosen over any other overloads of that operator. Note that since c++11 the compiler is allowed (and from c++17 required) to materialize the value directly inside the target object. This process is known as copy/move elision or (N)RVO, for (Named) Return Value Optimisation.
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