-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLvalueRvalue.cpp
More file actions
111 lines (93 loc) · 4.61 KB
/
LvalueRvalue.cpp
File metadata and controls
111 lines (93 loc) · 4.61 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* \file LvalueRvalue.cpp
* \brief
*
* \todo
*/
#include <StdStream/StdStream.h>
#include <StdTest/StdTest.h>
#include <Stl.h>
//-------------------------------------------------------------------------------------------------
int main(int, char **)
{
/**
* Lvalue
*
* Данный тип обычно находится с левой стороны выражения.
* Все переменные имеют lvalue тип. Тоесть то, что мы объявляем явно это lvalue
* Все перечисленное ниже это lvalue. Также результат функции которая возвращает lvalue будет
* того же типа.
*
* - Выражения, непосредственно обозначающие объект, non-modifiable в случае const-квалификации.
* Например, имя переменной, параметра функции и т.п.
* - Выражения ссылочных типов. non-modifiable в случае const-квалификации. В частности,
* результат вызова функций, возвращающих объекты по ссылке; выражения, состоящие из имен
* ссылочных переменных; операции преобразования к ссылочному типу и т.д.
* - Результат встроенной операции разыменования (*) — lvalue указуемого типа; non-modifiable
в случае const-квалификации
* - Результат встроенных префиксных операций ++, --
* - Имя функции — non-modifiable lvalue; может быть преобразовано к rvalue
* «указатель на функцию»
* - Имя массива — non-modifiable lvalue; может быть преобразовано к rvalue
* «указатель на первый элемент массива»
* - Строковые литералы — non-modifiable lvalue; может быть преобразовано к rvalue
* «указатель на char/wchar_t»
*/
// а - именованная переменная это lvalue
int a;
STD_UNUSED(a);
// переменная с модификатором const также lvalue
const char b = 'a';
STD_UNUSED(b);
// указатель не является исключением.
int* ptr{};
STD_UNUSED(ptr);
// функция возвращает lvalue
struct Foo
{
int& foo(int k)
{
static int b = k + 1;
return b;
}
};
/**
* Rvalue
*
* Встречается с правой стороны выражения. Все то что не имеет имени (выражения) это rvalue.
* Объект близкий к концу жизни(если речь к примеру идет о функции) также имеет тип rvalue.
* Также результат функции, которая не возвращает ссылку это rvalue.
*
* - Выражения, обозначающие временные объекты. В частности, результат вызова функций,
* возвращающих объекты не по ссылке; результат встроенных операций +, -. *, / и т.п.;
явное создание временной переменной int() или C();
преобразования не к ссылочным типам и т.д.
* - Результат встроенной операции взятия адреса (&) — rvalue типа указатель.
* - Результат встроенных постфиксных операций ++, --.
* - Литералы за исключением строковых.
* - Константы перечислений.
*/
// результат выражения 3 + 5 есть rvalue
Foo f;
f.foo(3 + 5);
// ошибка 7 - это rvalue, невозможно создать ссылку на rvalue
#if 0
int i = &7;
STD_UNUSED(i);
#endif
// true is rvalue
bool c = true;
STD_UNUSED(c);
// функция возвращает rvalue
struct Bar
{
int bar()
{
return 5;
}
};
return EXIT_SUCCESS;
}
//-------------------------------------------------------------------------------------------------
#if OUTPUT
#endif