Professional Documents
Culture Documents
Way back in chapter 1, we mentioned l-values and r-values, and then told you not to worry that much about them.
That was fair advice prior to C++11. But understanding move semantics in C++11 requires a re-examination of the
topic. So let’s do that now.
Every expression in C++ has two properties: a type (which is used for type checking), and a value category (which is
used for certain kinds of syntax checking, such as whether the result of the expression can be assigned to). In C++03
and earlier, l-values and r-values were the only two value categories available.
The actual definition of which expressions are l-values and which are r-values is surprisingly complicated, so we’ll take
a simplified view of the subject that will largely suffice for our purposes.
It’s simplest to think of an l-value (also called a locator value) as a function or an object (or an expression that
evaluates to a function or object). All l-values have assigned memory addresses.
When l-values were originally defined, they were defined as “values that are suitable to be on the left-hand side of an
assignment expression”. However, later, the const keyword was added to the language, and l-values were split into
two sub-categories: modifiable l-values, which can be changed, and non-modifiable l-values, which are const.
It’s simplest to think of an r-value as “everything that is not an l-value”. This notably includes literals (e.g. 5),
temporary values (e.g. x+1), and anonymous objects (e.g. Fraction(5, 2)). r-values are typically evaluated for their
values, have expression scope (they die at the end of the expression they are in), and cannot be assigned to. This
non-assignment rule makes sense, because assigning a value applies a side-effect to the object. Since r-values have
expression scope, if we were to assign a value to an r-value, then the r-value would either go out of scope before we
had a chance to use the assigned value in the next expression (which makes the assignment useless) or we’d have to
use a variable with a side effect applied more than once in an expression (which by now you should know causes
undefined behavior!).
In order to support move semantics, C++11 introduces 3 new value categories: pr-values, x-values, and gl-values. We
will largely ignore these since understanding them isn’t necessary to learn about or use move semantics effectively. If
you’re interested, cppreference.com has an extensive list of expressions that qualify for each of the various value
categories, as well as more detail about them.
L-value references
Prior to C++11, only one type of reference existed in C++, and so it was just called a “reference”. However, in C++11,
it’s sometimes called an l-value reference. L-value references can only be initialized with modifiable l-values.
Non-modifiable l-values No No
R-values No No
L-value references to const objects can be initialized with l-values and r-values alike. However, those values can’t be
modified.
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 1/18
05/05/2021 M.2 — R-value references | Learn C++
R-values Yes No
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.
R-value references
C++11 adds a new type of reference called an r-value 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:
1 int x{ 5 };
2 int &lref{ x }; // l-value reference initialized with l-value x
3 int &&rref{ 5 }; // r-value reference initialized with r-value 5
Modifiable l-values No No
Non-modifiable l-values No No
Modifiable l-values No No
Non-modifiable l-values No No
R-values Yes No
R-value references have two properties that are useful. First, r-value references extend the lifespan of the object they
are initialized with to the lifespan of the r-value reference (l-value references to const objects can do this too). Second,
non-const r-value references allow you to modify the r-value!
1 #include <iostream>
2
3 class Fraction
4 {
5 private:
6 int m_numerator;
7 int m_denominator;
8
9 public:
10 Fraction(int numerator = 0, int denominator = 1) :
11 m_numerator{ numerator }, m_denominator{ denominator }
12 {
13 }
14
15 friend std::ostream& operator<<(std::ostream& out, const Fraction &f1)
16 {
17 out << f1.m_numerator << '/' << f1.m_denominator;
18 return out;
19 }
20 };
21
22 int main()
23 {
24 auto &&rref{ Fraction{ 3, 5 } }; // r-value reference to temporary Fraction
25
26 // f1 of operator<< binds to the temporary, no copies are created.
27 std::cout << rref << '\n';
28
29 return 0;
30 } // rref (and the temporary Fraction) goes out of scope here
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 2/18
05/05/2021 M.2 — R-value references | Learn C++
This program prints:
3/5
As an anonymous object, Fraction(3, 5) would normally go out of scope at the end of the expression in which it is
defined. However, since we’re initializing an r-value reference with it, its duration is extended until the end of the block.
We can then use that r-value reference to print the Fraction’s value.
1 #include <iostream>
2
3 int main()
4 {
5 int &&rref{ 5 }; // because we're initializing an r-value reference with a literal, a
temporary with value 5 is created here
6 rref = 10;
7 std::cout << rref << '\n';
8
9 return 0;
10 }
10
While it may seem weird to initialize an r-value reference with a literal value and then be able to change that value,
when initializing an r-value with a literal, a temporary is constructed from the literal so that the reference is referencing
a temporary object, not a literal value.
R-value references are not very often used in either of the manners illustrated above.
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.
1 void fun(const int &lref) // l-value arguments will select this function
2 {
3 std::cout << "l-value reference to const\n";
4 }
5
6 void fun(int &&rref) // r-value arguments will select this function
7 {
8 std::cout << "r-value reference\n";
9 }
10
11 int main()
12 {
13 int x{ 5 };
14 fun(x); // l-value argument calls l-value version of function
15 fun(5); // r-value argument calls r-value version of function
16
17 return 0;
18 }
This prints:
As you can see, when passed an l-value, the overloaded function resolved to the version with the l-value reference.
When passed an r-value, the overloaded function resolved to the version with the r-value reference (this is considered
a better match than a l-value reference to const).
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 3/18
05/05/2021 M.2 — R-value references | Learn C++
Why would you ever want to do this? We’ll discuss this in more detail in the next lesson. Needless to say, it’s an
important part of move semantics.
1 int &&ref{ 5 };
2 fun(ref);
actually calls the l-value version of the function! Although variable ref has type r-value reference to an integer, it is
actually an l-value itself (as are all named variables). The confusion stems from the use of the term r-value in two
different contexts. Think of it this way: Named-objects are l-values. Anonymous objects are r-values. The type of the
named object or anonymous object is independent from whether it’s an l-value or r-value. Or, put another way, if r-
value reference had been called anything else, this confusion wouldn’t exist.
You should almost never return an r-value reference, for the same reason you should almost never return an l-value
reference. In most cases, you’ll end up returning a hanging reference when the referenced object goes out of scope at
the end of the function.
Quiz time
1 int main()
2 {
3 int x{};
4
5 // l-value references
6 int &ref1{ x }; // A
7 int &ref2{ 5 }; // B
8
9 const int &ref3{ x }; // C
10 const int &ref4{ 5 }; // D
11
12 // r-value references
13 int &&ref5{ x }; // E
14 int &&ref6{ 5 }; // F
15
16 const int &&ref7{ x }; // G
17 const int &&ref8{ 5 }; // H
18
19 return 0;
20 }
Show Solution
Index
Quentin
February 27, 2021 at 4:48 am · Reply
Hi Alex,
" An r-value reference is a reference that is designed to be initialized with an r-value (only)."
1 int x{11};
2 auto &&rref{x};
3 std::cout << rref << '\n';
This works fine and rvalue reference binds to lvalue of x. I am confused by the result.
nascardriver
March 4, 2021 at 7:59 am · Reply
&&, when used with templates or `auto` can collapse. Your `auto` turns into `int&`, so you're
forming an r-value reference to an `int`-reference, which collapses to an `int`-reference.
1 #include <type_traits>
2
3 // @decltype() "returns" the type of @rref
4 // @std::is_same_v checks if 2 types are the same
5 std::cout << std::is_same_v<decltype(rref), int&> << '\n';
yolo
March 23, 2021 at 12:18 pm · Reply
I don't really get why collapsing forms a problem. What kind of problems does it create?
The link doesn't say anything in particular.
nascardriver
March 24, 2021 at 8:06 am · Reply
goiu
January 23, 2021 at 6:13 am · Reply
Hi there!
What is the difference between an anonymous object and a temporary value?
yolo
March 23, 2021 at 12:27 pm · Reply
Take it with a grain of salt. Anonymous objects can be temporary values but temporary values
cannot be anonymous objects. Anonymous objects can be
yeokaiwei
January 7, 2021 at 10:20 pm · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 5/18
05/05/2021 M.2 — R-value references | Learn C++
1. Feedback on "R-value references as function parameters" example
Based on the tutorial settings in Chapter 1, there will be warnings for the void fun() examples, while
using MSVS2019.
yeokaiwei
January 7, 2021 at 10:09 pm · Reply
1 #include <iostream>
2
3 int main()
4 {
5 int &&rref{ 5 }; // because we're initializing an r-value reference with a literal,
a temporary with value 5 is created here
6 rref = 10;
7 std::cout << rref << '\n';
8
9 return 0;
10 }
1 #include <iostream>
2
3 int main()
4 {
5 int rref{ 5 }; // I just removed the &&
6 rref = 10;
7 std::cout << rref << '\n';
8
9 return 0;
10 }
In the less intuitive example, what's the difference between the above code and the latter code?
Hovsep_Papoyan
December 1, 2020 at 3:55 am · Reply
#include <iostream>
// example 1
/*
struct s {};
const s f()
{
return s{};
}
int main()
{
const s obj;
fun(std::move(obj)); // l-value reference
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 6/18
05/05/2021 M.2 — R-value references | Learn C++
fun(f()); // l-value reference
return 0;
}
*/
// example 2
void fun(const int &lref) // l-value arguments will select this function
{
std::cout << "l-value reference to const\n";
}
int main()
{
const int obj{};
fun(std::move(obj)); // l-value reference to const
fun(f()); // r-value reference
return 0;
}
sv
August 1, 2020 at 1:00 am · Reply
i have a question
what would be the datatype of the anonymous object created for an expression?
for ex: x=y*10;
here the anonymous object(y*10)'s datatype? would it depend on the datatype of 'y' and '10' or 'x' ?
nascardriver
August 3, 2020 at 5:03 am · Reply
All of them.
`y * 10` can yield a different type than `y * 10.0`, so 10's type matters.
`y * 10` can yield a different type depending on what `y` is (eg. if `y` is a `double`, the result is a double. if
`y` is an `int`, the result is an `int`).
Then you need something that can be on the right-hand-side of an assignment to `x`. To call the assignment
operator or constructor of `x`'s type there might be another conversion.
sv
August 3, 2020 at 5:19 am · Reply
So if y=2*e32, where y is of type int, then x will be assigned garbage value as (y*10)
exceeds the limit of int... In that case one of the value should be casted to bigger
datatype...ok thanks
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 7/18
05/05/2021 M.2 — R-value references | Learn C++
Alven
July 24, 2020 at 7:53 pm · Reply
int main()
{
int x{};
int &&ref1{ &x }; // A
Fun &&f = fun; // B
Fun ff = f; // C
Fun fff = std::move(f); //D
}
could this main function pass the compilation? &x is a lvalue or rvalue ? and what about fun?
nascardriver
July 26, 2020 at 1:47 am · Reply
If you want to check if something compiles but you can't be bothered creating a file, you can use
godbolt.org
Alven
July 26, 2020 at 2:28 am · Reply
int main()
{
funPass(fun);
}
that works. if fun is a lvalue , why the funPass could accept it as its input parameter should be a
rValue? thanks.
nascardriver
July 26, 2020 at 2:31 am · Reply
zara
May 29, 2020 at 9:14 am · Reply
Hi,
I was wondering in the following example, if 'x' is an l-value or r-value?
1 int x{10};
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 8/18
05/05/2021 M.2 — R-value references | Learn C++
2 int z {20};
3
4 int z=x;
How about the following? On the right-side of the 'greeting', are they r-value? how about the right-side of 'str', is it r-
value too?
nascardriver
May 30, 2020 at 12:36 am · Reply
`x` and `first_name` are a lvalues. If you can modify something, it's a good sign that it's an
lvalue.
`first_name + last_name` is a prvalue, because `operator+(const std::string&, const std::string&)` returns by
value.
Michael
March 30, 2020 at 6:40 pm · Reply
Hi nascardriver,
Thanks for making this tutorial. It is very helpful.
Could you help me confirm that when function argument is a reference(regardless of either l-value or r-value ref)
the function overloading selection logic applied by C++ compiler is different from non-ref arguments?
However I am still very puzzled by the following example despite reading your explanation:
1 void fun(const int &lref) // l-value arguments will select this function // <-- label A
2 {
3 std::cout << "l-value reference to const\n";
4 }
5
6 void fun(int &&rref) // r-value arguments will select this function // <-- label B
7 {
8 std::cout << "r-value reference\n";
9 }
10
11 int main()
12 {
13 int &&ref{ 5 };
14 fun(ref); // selects the l-value ref version ?!
15 return 0;
16 }
For example, compiler should always pick the function with matching type signature, right?
1 void fun1(int y) {
2 std::cout << "y is of type int\n";
3 }
4
5 void fun1(double y) {
6 std::cout << "y is of type double\n";
7 }
8
9 int main() {
10 int y;
11 fun1(y); // selects the int version.
12 return 0;
13 }
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 9/18
05/05/2021 M.2 — R-value references | Learn C++
Here in my `fun1`, if the I cam calling with the symbol `y` of type double, it will always pick `void fun1(double x)`
because the type of argument x is double.
But in your example, the case is different despite that the symbole `x` has a matching type to function `label B`.
nascardriver
March 31, 2020 at 5:35 am · Reply
There's nothing special about the overload selection. What you're observing is happening
because `ref` is not an r-value. It's a reference to an r-value.
1 #include <utility>
2
3 void fn(int&&){}
4
5 int main()
6 {
7 int&& i{ 5 };
8 fn(i); // Doesn't work.
9 fn(5); // ok
10 fn(std::move(i)); // ok
11 }
hellmet
November 30, 2019 at 6:06 am · Reply
I think the Fraction example (just after r-value) would be much more convincing to readers if the copy
constructor was explicitly deleted.
nascardriver
December 2, 2019 at 4:29 am · Reply
Adding unnecessary code while introducing something new can be confusing. I added a
comment instead, stating that no copies are made.
hellmet
December 2, 2019 at 4:56 am · Reply
Vasant
June 3, 2019 at 11:28 pm · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 10/18
05/05/2021 M.2 — R-value references | Learn C++
Hi Alex,
I removed the function which takes an lvalue reference and as expected, compiler reported an error
while invoking the function with an lvalue.
1 //void fun(const int &lref) // l-value arguments will select this function
2 //{
3 // std::cout << "l-value reference to const\n";
4 //}
5
6
7 void fun(int &&rref) // r-value arguments will select this function
8 {
9 std::cout << "r-value reference\n";
10 }
11
12 int main()
13 {
14 int x = 5;
15 fun(x); //DOESN'T COMPILE // l-value argument calls l-value version of function
16 fun(5); // r-value argument calls r-value version of function
17
18 return 0;
19 }
20
21 However, if i make the rvalue reference function a template function, invoking it with
an lvalue compiles. Can you please explain? Thanks.
22
23 template<typename T>
24 void fun(T &&rref) // r-value arguments will select this function
25 {
26 std::cout << rref;
27 std::cout << "r-value reference\n";
28 }
29
30 int main()
31 {
32 int x = 5;
33 fun(x); // l-value argument calls l-value version of function
34 fun(5); // r-value argument calls r-value version of function
35
36 return 0;
37 }
nascardriver
June 4, 2019 at 8:10 am · Reply
Hi!
Line 33 calls `fun<int&>(x)`. First a temporary reference to `x` is created, this reference can then be r-value-
referenced by @fun.
Since the non-template `fun` only accepts `int&&`, not `int&&&`, it won't compile. (You can't use `int&&&` as
a type manually (But you can if you use a type alias)).
Asgar
February 27, 2019 at 5:34 pm · Reply
Hi.
Is this an l-value?
Suppose there was a public member function named foo() in Fraction, could we then write a statement like below?
1 new Fraction(3,5)->foo(); // If we can do this, does it not indicate that new Fraction
(3,5) is an l-value?
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 11/18
05/05/2021 M.2 — R-value references | Learn C++
nascardriver
February 28, 2019 at 7:32 am · Reply
Asgar
February 28, 2019 at 9:36 am · Reply
Oh, I see the memory leak now. But even then, is being able to be assigned with something a pre-
requisite for an l-value?
According to this page, all l-values have assigned memory addresses. So, isn't anything that evaluates
to a name or memory address an l-value?
nascardriver
March 2, 2019 at 3:57 am · Reply
is an initialization. Assigning to it doesn't make sense -> It's not an lvalue (It's a prvalue).
1 const int i{ 0 };
2 i = 3;
We cannot assign to @i, because it's const. But other than const, there's no logical reason not to
be able to assign to @i -> @i is an lvalue.
What do you mean when "However, since we’re initializing an r-value reference with it, its duration is
extended until the end of the block." (referring to this code -> Fraction &&rref = Fraction(3, 5);)
Even if you initialize Fraction rref = Fraction(3, 5), or Fraction& rref = Fraction(3, 5) doesn't it call the same
constructor and extends its lifetime as well?
Alex
October 11, 2018 at 12:25 pm · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 12/18
05/05/2021 M.2 — R-value references | Learn C++
1 Fraction rref = Fraction(3, 5);
Creates a temporary fraction and then uses the copy constructor to initialize rref. No extension necessary
since the temporary fraction can die after being copied.
is illegal because you can't have a non-const l-value reference pointing to an r-value.
TC
September 25, 2018 at 9:36 pm · Reply
Hi Alex,
As you can see, the r-value and the local class variable both produce the same outputs.
So what is the purpose of using r-value over the local class variable?
Thanks,
TC
1 int main()
2 {
3 Fraction &&rref = Fraction(3, 5); // r-value reference to temporary Fraction
4 Fraction ref(3, 5); // r-value reference to temporary Fraction
5 std::cout << rref << '\n';
6 std::cout << ref << '\n';
7
8 return 0;
9 } // rref (and the temporary Fraction) goes out of scope here
Alex
September 27, 2018 at 9:11 am · Reply
There is zero benefit to using references in this case. This is equally true of using a const l-
value reference in said case.
As the lesson notes, r-value references are more typically used as function parameters when you want to
differentiate function behaviors for l-value and r-value arguments.
TC
September 27, 2018 at 9:25 am · Reply
Topherno
May 16, 2018 at 12:20 pm · Reply
"First, r-value references extend the lifespan of the object they are initialized with to the lifespan of the r-value
reference. l-value references to const objects can do this too, but it’s far more useful for r-value references since r-
values have expression scope otherwise."
What exactly do you mean by "since r-values have expression scope otherwise"? If an object with expression
scope is initialized with a l-value ref to a const object, then its lifespan is also extended past expression scope, just
like with a r-value ref.
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 13/18
05/05/2021 M.2 — R-value references | Learn C++
Basically, what's confusing me is that with respect to extending lifespans, I don't see the advantage that r-value
refs have over l-value refs to const objects. On the other hand, the fact that r-value refs can modify their
corresponding r-values is a clear advantage. Thanks in advance :)
Alex
May 19, 2018 at 1:41 pm · Reply
By "expression scope", I mean that r-values are temporary values that typically only live until
the end of the expression they're in.
I take your second point -- there's no real advantage of r-values references over const l-value references in
terms of lifespan extension. I've removed the latter part of the original sentence accordingly.
Ryan
May 7, 2018 at 12:24 pm · Reply
"You should almost never return an r-value reference, for the same reason you should almost never
return an l-value reference. In most cases, you’ll end up returning a hanging reference when the
referenced object goes out of scope at the end of the function."
But I thought that "r-value references extend the lifespan of the object they are initialized with to the lifespan of the
r-value reference." So, shouldn't returning an r-value reference extend the lifespan of the r-value to the control of
the function caller code that is receiving the return value?
Alex
May 10, 2018 at 8:00 pm · Reply
What happens is: inside getFoo() a temporary Foo is constructed. Since this function returns by value, a
copy of the Foo is returned, and the original Foo is destroyed. That returned Foo then has its lifetime
extended by being bound to the rvalue reference in main.
In this example, inside getFoo() a temporary Foo is constructed. At the end of the function, this Foo gets
destroyed, and an r-value reference to the destroyed Foo is returned. Thus ref is left as a dangling pointer.
In the first case, the lifetime can be extended before the Foo is destroyed. In the second case, the Foo gets
destroyed before its lifetime can be extended.
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 14/18
05/05/2021 M.2 — R-value references | Learn C++
skv
February 24, 2018 at 12:08 pm · Reply
Good article!!!
Alex, could you plz explain why R-value references for 'user-defined data types' are modifiable
but not for 'built-in data types'?
nascardriver
February 25, 2018 at 4:54 am · Reply
Hi skv!
Mind giving an example? Alex showed that r-value references to built-in data types can be modified.
1 #include <iostream>
2
3 int main()
4 {
5 int &&rref = 5; // because we're initializing an r-value reference with a lit
eral, a temporary with value 5 is created here
6 rref = 10;
7 std::cout << rref;
8
9 return 0;
10 }
Prints 10
Isak
February 3, 2018 at 11:49 am · Reply
Alex
February 5, 2018 at 10:03 am · Reply
Both are true. You should never return a reference to a local l-value, as it will go out of scope
and leave you with a hanging reference. You should almost never return an l-value reference
period, as there are only a few cases where it really makes sense to do so. The main time I see this occur is
when overloading operators, when we want to return either the implicit object (or std::ostream) by reference
so we can chain operators.
Isak
February 11, 2018 at 10:48 am · Reply
Summer
October 26, 2017 at 11:11 pm · Reply
Hey Alex, I have a question, why don't you mention the knowledge about 'universal reference' and
'perfect forwarding' in this chapter? I think this part is quite related. But I don't know if they are not
important at all.
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 15/18
05/05/2021 M.2 — R-value references | Learn C++
Thank you very much for the wonderful tutorial. Whenever I seek for something I come to your tutorial firstly to find
the answer, it is so clearly explained and solved me many problems. That's also the reason why I'm curious about
my question above.
Alex
October 30, 2017 at 9:35 am · Reply
Luhan
November 30, 2017 at 7:23 am · Reply
I've found a very good article about forward declaration Alex, maybe it can help you
someday to write something about it , and some other readers interested in it.
[link]http://thbecker.net/articles/rvalue_references/section_01.html.
Mohsen
August 15, 2017 at 9:07 am · Reply
Alex
August 16, 2017 at 10:32 am · Reply
I'm not aware of whether any good socket programming tutorials exist or not. Sorry!
Zoran
July 29, 2017 at 6:22 am · Reply
Hello, Alex,
I added a r-value reference y to your example and then called fun with it:
1 int main()
2 {
3 int x = 5;
4 fun(x); // l-value argument calls l-value version of function
5 fun(5); // r-value argument calls r-value version of function
6
7 int &&y = 5;
8 fun(y); // I expected this to call r-value version on fun.
9
10 return 0;
11 }
Alex
July 29, 2017 at 10:31 pm · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 16/18
05/05/2021 M.2 — R-value references | Learn C++
Because a named r-value reference is actually an l-value. It has a name, and persists beyond
an expression.
Mike
January 17, 2019 at 3:07 am · Reply
^^This. If you haven't done so somewhere else (in which case, could you inform me
where), it might be worthwhile pointing this out either here, or on the next page). I was
scratching my head trying to figure out why some object I was initialising with an R-value reference
wasn't using the move constructor!
Alex
January 21, 2019 at 11:43 am · Reply
Martin
July 29, 2017 at 12:45 am · Reply
CA
July 13, 2017 at 7:23 am · Reply
What is the difference between const reference and lvalue reference to const objects? Can we use
the second one for the copy constructor? The reason that I am asking is that following code gives the
error "member function already defined"
1 class Foo {
2 public:
3 Foo() {
4 cout << "constructorn";
5 }
6
7 ~Foo() {
8 cout << "destructorn";
9 }
10
11 Foo(const Foo& f) {
12 cout << "copy constructorn";
13 }
14
15 Foo(Foo const& f) {
16 cout << "copy constructorn";
17 }
18 };
19
20
21 int main(int argc, char** argv) {
22 Foo f1;
23 return 0;
24 }
PS: Thanks Alex for this excellent tutorial. I almost done with all!!!
Alex
July 13, 2017 at 10:41 am · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 17/18
05/05/2021 M.2 — R-value references | Learn C++
A "const reference" is just a shorthand name for a "l-value reference to const object".
"const Foo&" and "Foo const&" are the same thing to the compiler.
Aakash
February 26, 2017 at 4:37 am · Reply
hello alex,
in the quiz, why the //D will compile
Alex
February 26, 2017 at 12:42 pm · Reply
aca4life
February 21, 2017 at 5:37 am · Reply
Hi Alex,
2) Quiz: "State whether ... will compile or not!" or "State which .. won't compile!"
Alex
February 21, 2017 at 1:33 pm · Reply
https://www.learncpp.com/cpp-tutorial/rvalue-references/ 18/18