# 02 Лекция, rvalue-ссылки, move-семантика, xvalue, copy elision, lifetime extension
(03.09.2022)
> [TOC]
## Move и r-value
До C++11
```cpp
#include <vector>
#include <string>
class str
{
private:
char *data;
size_t len;
str(str const&); //copy
str(str& prev): //move - нельзя сделать r-value
data(prev.data),
len(prev.len)
{
prev.data = nullptr;
prev.len = 0;
}
};
int main ()
{
std::vector<std::string> vec;
std::string s;
vec.push_back(s);
str b;
}
```
---
Отличие l-value и r-value
```c
int main()
{
int a;
//l-value
int &b = a;
//int &c = 42; error
//r-value
//int &&d = a; error
int &&e = 42;
}
```
---
Как надо:
```c
class str
{
private:
char *data;
size_t len;
str(str const&); //copy construct
str(str &&) //move construct, r-value
str& operator=(str const&); //copy operator
str& operator=(str &&; //move operator, r-value
};
```
Как сделать move на локальную переменную:
```cpp
int main()
{
str a();
str b(static_cast<str&&>(a)); //каст к r-value ссылке
str b(move(a)); //тоже самое, только из стандартной библиотеки
}
```
---
Нужно не забывать мувать обьекты внутри класса:
```cpp
struct person
{
std::string name;
person(std::string &&name) : name(std::move (name)) {}
person(std::string name, std:: string surname)
: name(std::move(name))
, name(std::move(surname))
{}
}
```
**ИЛИ**
Как надо принимать аргументы:
```cpp
struct person
{
std::string name;
std::string surname;
person(std::string name, std::string surname) //принимает по значению
: name(std::move(name))
, surname(std::move(surname))
{}
}
```
**Делать копию или нет, в случае передачи по значению - выбирает вызывающая сторона.**
---
Ошибка новичка: (пытаться избежать копирования там где его нет!)
Норм:
```cpp
std::string foo()
{
std::string res;
//code
return res; //копирования не будет!
}
```
БРЕД: (уничтожается локальная переменная при выходке из функции)
```cpp
std::string& foo()
{
std::string res;
//code
return res;
}
```
БРЕД 2: (уничтожается локальная переменная при выходке из функции)
```cpp
std::string&& foo()
{
std::string res;
//code
return std::move(res);
}
```
---
## l-value, r-value и x-value

```cpp
struct mytype{};
mytype prvalue(); //r-value записывает результат в память
mytype& lvalue(); //l-value
mytype&& xvalue(); //x-value
void foo(mytype);
void foo(mytype const&);
void foo(mytype&&);
mytype test()
{
foo(prvalue()); //r-value, mytype&&
foo(lvalue()); //l-value, mytype const&
foo(xvalue()); //x-value, mytype&&
return prvalue(); //RVO
return lvalue(); //non RVO
return xvalue(); //NON RVO
mytype const &ref = prvalue(); //r-value, life extension
mytype const &lref = lvalue(); //l-value, no left extension
mytype const &xref = xvalue(); //x-value, no left extension
mytype &&ref1 = prvalue(); //r-value, life extension
//mytype &&lref1 = lvalue(); //compilation error
mytype &&xref1 = xvalue(); //x-value, no left extension
}
```
# Оглавление
> [TOC]