0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: rvalue, lvalue, std::move()</p>
1
<p>Теги: rvalue, lvalue, std::move()</p>
2
<p>В одной из предыдущих статей мы рассматривали move-семантику в C++. Продолжим тему и поговорим про rvalue и lvalue.</p>
2
<p>В одной из предыдущих статей мы рассматривали move-семантику в C++. Продолжим тему и поговорим про rvalue и lvalue.</p>
3
<p>Главное отличие rvalue и lvalue заключается в том, что объекты rvalue можно переместить, в то время как объекты lvalue - лишь скопировать. Рассматривать это лучше на практических примерах:</p>
3
<p>Главное отличие rvalue и lvalue заключается в том, что объекты rvalue можно переместить, в то время как объекты lvalue - лишь скопировать. Рассматривать это лучше на практических примерах:</p>
4
<p>Данный код будет функционировать не так, как от него ждут. К примеру, std::move() всё ещё конвертирует lvalue в rvalue, однако конвертация сохраняет все модификаторы, включая const. Потом компилятор выбирает между 2-х конструкторов класса String наиболее подходящий. Так как компилятор не может отправить const rlvaue туда, где ожидается non-const rvalue, компилятор выбирает конструктор копирования, а const rvalue конвертируется обратно в const lvalue.</p>
4
<p>Данный код будет функционировать не так, как от него ждут. К примеру, std::move() всё ещё конвертирует lvalue в rvalue, однако конвертация сохраняет все модификаторы, включая const. Потом компилятор выбирает между 2-х конструкторов класса String наиболее подходящий. Так как компилятор не может отправить const rlvaue туда, где ожидается non-const rvalue, компилятор выбирает конструктор копирования, а const rvalue конвертируется обратно в const lvalue.</p>
5
<p>Какие из этого можно сделать выводы?<strong>Необходимо следить за модификаторами объектов</strong>, ведь они учитываются в случае выбора одной из перегрузок функции.</p>
5
<p>Какие из этого можно сделать выводы?<strong>Необходимо следить за модификаторами объектов</strong>, ведь они учитываются в случае выбора одной из перегрузок функции.</p>
6
<p>Теперь давайте перейдем ко второму примеру. Он демонстрирует правило, согласно которому результат функции и аргументы могут быть как lvalue, так и rvalue, но параметры функций при этом могут быть лишь lvalue. Под аргументом в данном случае подразумевается то, что передаётся в нашу функцию. Аргумент инициализирует параметр, доступный непосредственно внутри функции.</p>
6
<p>Теперь давайте перейдем ко второму примеру. Он демонстрирует правило, согласно которому результат функции и аргументы могут быть как lvalue, так и rvalue, но параметры функций при этом могут быть лишь lvalue. Под аргументом в данном случае подразумевается то, что передаётся в нашу функцию. Аргумент инициализирует параметр, доступный непосредственно внутри функции.</p>
7
<p>И хотя параметр string функции f() и имеет тип rvalue-ссылки, все же он является lvalue, то есть требует явной конвертации в rvalue непосредственно перед передачей в функцию g(). А вот как раз этим и занимается std::move().</p>
7
<p>И хотя параметр string функции f() и имеет тип rvalue-ссылки, все же он является lvalue, то есть требует явной конвертации в rvalue непосредственно перед передачей в функцию g(). А вот как раз этим и занимается std::move().</p>
8
<p><em><a>Источник</a></em></p>
8
<p><em><a>Источник</a></em></p>
9
9