|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||||||||||
Возвращаемый тип как rvalue reference23.05.2018, 15:35. Показов 5934. Ответов 20
Метки нет (Все метки)
Нашел интересный пример в книге Мейерса Эффективный и современный С++.
Ведь что бы переместить values в вызываемую сторону этого делать не обязательно. Достаточно было бы написать так:
П.С: конструктор по умолчанию я добавил сам (в книге его нет)... забыл убрать при публикации
0
|
|||||||||||
| 23.05.2018, 15:35 | |
|
Ответы с готовыми решениями:
20
C++ expressions - rvalue, glvalue, prvalue, xvalue, lvalue, а также rvalue reference: что есть что? RVALUE Ссылка, error: cannot bind non-const lvalue reference of type 'String&' to an rvalue of type 'String'| Rvalue reference |
|
|
||||||
| 23.05.2018, 16:07 | ||||||
|
del
Добавлено через 25 минут Мне кажется, что дело в следующем. values в данном случае станет xvalue Соответственно в качестве возвращаемого значения мы получим rvalue(xvalue). И тогда в случае:
Но это всё лирика
0
|
||||||
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
||||||||||||||||
| 23.05.2018, 16:34 | ||||||||||||||||
|
Любопытно, что код
Мне кажется, тут дело в том, что возврат по правой ссылке более безопасен и задействует меньше неочевидных механизмов. Добавлено через 2 минуты И потом ожидается, что метод data таки возвращает ссылку, а не объект.
1
|
||||||||||||||||
| 23.05.2018, 16:35 | ||||||
|
Не по теме: Mirmik, А (N)RVO было бы только при?
0
|
||||||
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
| 23.05.2018, 16:38 | |
|
А зачем задействовать RVO? Это же ничего не даёт.
0
|
|
| 23.05.2018, 16:38 | |
|
Не по теме: Mirmik, Точно, объект то не локальный, не временный
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 23.05.2018, 17:12 [ТС] | |
|
Peoples,
RVO/NRVO вроде как работает только для локальных объектов функции... А в том примере возвращается поле, поэтому думаю компилятор не имеет право применять подобные оптимизации... Mirmik, Не очень понятно про неочевидные механизмы. Согласно примеру из книги, конечная цель это при вызове data()&& переместить вектор в вызывающую сторону, что и происходит даже если не вернуть rvalue ссылку а просто сделать move. Я думаю что в случае отсутствия при возврате rvalue ссылки, могут возникнуть дополнительные копии (т.е гарантий что сработает только перемещение у нас нет) - это конечно же лишь предположение. Буду рад если кто нибудь уточнит
0
|
|
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
| 23.05.2018, 17:55 | |
|
Если без правой ссылки, возвращен из функции будет временный объект, инициализированный конструктором перемещения, который уже будет присвоен целевому объекту.
Я не знаю наверняка, но компилятор это дело, вероятно оптимизирует и разницы не будет. (большой знак вопроса.) А если вы вернете правую ссылку, то никаких сложных возвратов не будет. Будет просто присваивание перемещением.
1
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 24.05.2018, 13:43 [ТС] | ||
|
Хотелось бы получить более точный ответ, почему так происходит
0
|
||
|
|
|
| 24.05.2018, 13:44 | |
|
"Если возвращать такую (правую) ссылку, то дело перемещать или копировать, или вообще ничего не делать уже на вызывающей стороне делается." (с) Авторитетный источник
Кликните здесь для просмотра всего текста
std::move ничего не перемещает, как известно
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 24.05.2018, 14:08 [ТС] | |
|
Peoples,
Ну по большому счету в данном случае это же не имеет значения, на какой стороне что делается ![]() Интересен сам результат, который является одинаковым в обоих случаях.... Вычитано с тырнета: стандарт позволяет рассматривать возвращаемое выражение как rvalue, соответственно если мы применим move к полю, то оно может быть перемещено в вызывающую сторону (т.е не гарантировано). Пункт о том где это написано - не знаю, надо покопаться. То есть насколько я понимаю подобное поведение (без rvalue ссылки) допустимо стандартом, но не гарантируется т.е мы просто полагаемся на оптимизации компилятора. А в случае с rvalue ссылкой у компилятора других вариантов нет. Это конечно же не утверждение, а лишь мои предположения, фактов у меня нет.
0
|
|
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|||||||||||
| 24.05.2018, 14:39 | |||||||||||
|
...
Ну, это вопрос не о том, что, а о том, как. Если вам нужно переместить данные в вызывающий объект.
Но концептуально вариант с правой ссылкой лучше. Если вы возвращаете DataType, вы создаете временный объект, перемещаете в него данные и возвращаете его. Если вы возвращаете DataType&&, вы просто возвращаете ссылку на данные, и вызывающий код уже решает, что с ними делать. Может вообще оставить все как есть и ничего не перемещать. Добавлено через 2 минуты Может быть я хочу сделать:
2
|
|||||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 24.05.2018, 22:04 [ТС] | |
|
Mirmik,
В принципе меня устраивает ваш ответ, кроме того что вы говорите если возвращаемый тип DataType, то это копия и отсутствие ссылок на стандарт (потому как ситуация не очень то и очевидная). Но в любом случае благодарю за ответ.
0
|
|
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||
| 24.05.2018, 22:50 | ||
Сообщение было отмечено Undisputed как решение
Решение
1
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 24.05.2018, 23:45 [ТС] | |
|
rat0r,
Спасибо! Переводить тип возвращаемого значения это конечно сильно
0
|
|
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
| 25.05.2018, 11:57 | |
|
Ух ты ж ё...
0
|
|
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
||
| 21.05.2019, 17:00 | ||
|
Но вообще это Мейерс решил, что лучше бы возвращался
DataType&&
0
|
||
|
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
|
|||||||||||||
| 21.05.2019, 20:34 | |||||||||||||
|
https://rextester.com/QFNOQ77094
Наглядно видно, что: 1. В первом случае получаем невалидную ссылку. Попытка использовать такую ссылку - ub 2. Во втором случае выполняется копия объекта. Не эффективно. 3. Мембер был перемещен во временный объект. время жизни временного объекта - до конца работы с итоговой ссылкой. 4. Итоговая ссылка продлила время жизни всего класса Widget С одной стороны это наиболее эффективный способ. С другой - компиляторы до сих пор не осилили эту часть стандарта. Можно запросто нарваться на протухшую ссылку. Итого: 3й вариант самый лучший: надежный и эффективный. (c) hoggy
сообщение скопировано с другого форума.
0
|
|||||||||||||
|
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
|
|||||||
| 21.05.2019, 21:27 | |||||||
0
|
|||||||
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|
| 21.05.2019, 21:27 | |
|
Методы, возвращающие &&-ссылки должны быть только кастами (каким является
std::move, например). А код в примере рано или поздно приведёт к UB.eva2326, пояснил довольно подробно. Возвращать std::move(x) стоит лишь если x — поле класса, в случае локальной переменной или аргумента сработает (N)RVO или move, т.к. результат функции, возвращённой по значению в любом случае является rvalue с точки зрения вызывающего кода.
0
|
|
| 21.05.2019, 21:27 | |
|
Помогаю со студенческими работами здесь
20
Rvalue reference Rvalue reference and lambda std::move, rvalue reference Rvalue reference. Что происходит в коде? что за возвращаемый тип, и как работает функция? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога
Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
|
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога
Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
|
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога
Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
|
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
|
|
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога
В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
|
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
|
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога
Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
|
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
|