forked from cirosantilli/cpp-cheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rvalue_reference.cpp
90 lines (67 loc) · 1.91 KB
/
rvalue_reference.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
# rvalue reference
# &&
http://www.artima.com/cppsource/rvalue.html
C++11
New type of reference.
Old references are referred to as lvalue references,
since they must be initialized by lvaues.
Denoted by double ampersand `&&`.
There is one difference between them and lvalue references:
rvalue references can only be initialized by both rvalues,
unlike lvalue references which can only be initialized by lvalues
(except if they are const).
Main motivation: implement move semantics.
*/
#include "common.hpp"
#if __cplusplus >= 201103L
/* Pair of function overload based only on if argument is an rvalue or a lvalue. */
std::string overloadRLvalue(int& i) {
return "lval";
}
std::string overloadRLvalue(int&& i) {
return "rval";
}
/*
ERROR: ambiguous with both of the above, because in C++:
int i = lvalue;
Leads to copy construction (ambiguous with the `&` overload).
int i = rvalue;
Leads to move construction (ambiguous with the `&&` overload).
*/
/*
std::string overloadRLvalue(int i) {
return "val";
}
*/
#endif
int main() {
#if __cplusplus >= 201103L
/*
Cannot be bound to an lvalue on stack.
This is the *key* property of rvalue references, since it allows function overload
to differentiate lvalues from rvalues, and thus implement move contructors.
*/
{
int i = 0;
int&& irr = 1;
// ERROR: i is not rvalue, it is a lvalue!
//int&& irrBad = i;
}
// On all other aspects besides initialization, rvalue references
// are identical to lvalue references.
{
int&& irr = 0;
assert(irr == 0);
irr = 1;
assert(irr == 1);
}
// Function overload can distinguish rvalues from lvalues.
// This is essential for move semantics.
{
int i;
assert(overloadRLvalue(i) == "lval");
assert(overloadRLvalue(1) == "rval");
}
#endif
}