900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|||||||||||
1 | |||||||||||
Возвращаемый тип как rvalue reference23.05.2018, 15:35. Показов 5441. Ответов 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 Rvalue reference |
23.05.2018, 16:07 | 2 | |||||
del
Добавлено через 25 минут Мне кажется, что дело в следующем. values в данном случае станет xvalue Соответственно в качестве возвращаемого значения мы получим rvalue(xvalue). И тогда в случае:
Но это всё лирика
0
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
||||||||||||||||
23.05.2018, 16:34 | 3 | |||||||||||||||
Любопытно, что код
Мне кажется, тут дело в том, что возврат по правой ссылке более безопасен и задействует меньше неочевидных механизмов. Добавлено через 2 минуты И потом ожидается, что метод data таки возвращает ссылку, а не объект.
1
|
Peoples
|
|||||
23.05.2018, 16:35
#4
|
|||||
Не по теме: Mirmik, А (N)RVO было бы только при?
0
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
23.05.2018, 16:38 | 5 |
А зачем задействовать RVO? Это же ничего не даёт.
0
|
Peoples
|
23.05.2018, 16:38
#6
|
Не по теме: Mirmik, Точно, объект то не локальный, не временный
0
|
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|
23.05.2018, 17:12 [ТС] | 7 |
Peoples,
RVO/NRVO вроде как работает только для локальных объектов функции... А в том примере возвращается поле, поэтому думаю компилятор не имеет право применять подобные оптимизации... Mirmik, Не очень понятно про неочевидные механизмы. Согласно примеру из книги, конечная цель это при вызове data()&& переместить вектор в вызывающую сторону, что и происходит даже если не вернуть rvalue ссылку а просто сделать move. Я думаю что в случае отсутствия при возврате rvalue ссылки, могут возникнуть дополнительные копии (т.е гарантий что сработает только перемещение у нас нет) - это конечно же лишь предположение. Буду рад если кто нибудь уточнит
0
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
23.05.2018, 17:55 | 8 |
Если без правой ссылки, возвращен из функции будет временный объект, инициализированный конструктором перемещения, который уже будет присвоен целевому объекту.
Я не знаю наверняка, но компилятор это дело, вероятно оптимизирует и разницы не будет. (большой знак вопроса.) А если вы вернете правую ссылку, то никаких сложных возвратов не будет. Будет просто присваивание перемещением.
1
|
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|
24.05.2018, 13:43 [ТС] | 9 |
Проверял на трех компиляторах, с правой ссылкой или без нее - результат одинаковый...
Хотелось бы получить более точный ответ, почему так происходит
0
|
24.05.2018, 13:44 | 10 |
"Если возвращать такую (правую) ссылку, то дело перемещать или копировать, или вообще ничего не делать уже на вызывающей стороне делается." (с) Авторитетный источник
Кликните здесь для просмотра всего текста
std::move ничего не перемещает, как известно
0
|
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|
24.05.2018, 14:08 [ТС] | 11 |
Peoples,
Ну по большому счету в данном случае это же не имеет значения, на какой стороне что делается Интересен сам результат, который является одинаковым в обоих случаях.... Вычитано с тырнета: стандарт позволяет рассматривать возвращаемое выражение как rvalue, соответственно если мы применим move к полю, то оно может быть перемещено в вызывающую сторону (т.е не гарантировано). Пункт о том где это написано - не знаю, надо покопаться. То есть насколько я понимаю подобное поведение (без rvalue ссылки) допустимо стандартом, но не гарантируется т.е мы просто полагаемся на оптимизации компилятора. А в случае с rvalue ссылкой у компилятора других вариантов нет. Это конечно же не утверждение, а лишь мои предположения, фактов у меня нет.
0
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|||||||||||
24.05.2018, 14:39 | 12 | ||||||||||
...
Ну, это вопрос не о том, что, а о том, как. Если вам нужно переместить данные в вызывающий объект.
Но концептуально вариант с правой ссылкой лучше. Если вы возвращаете DataType, вы создаете временный объект, перемещаете в него данные и возвращаете его. Если вы возвращаете DataType&&, вы просто возвращаете ссылку на данные, и вызывающий код уже решает, что с ними делать. Может вообще оставить все как есть и ничего не перемещать. Добавлено через 2 минуты Может быть я хочу сделать:
2
|
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|
24.05.2018, 22:04 [ТС] | 13 |
Mirmik,
В принципе меня устраивает ваш ответ, кроме того что вы говорите если возвращаемый тип DataType, то это копия и отсутствие ссылок на стандарт (потому как ситуация не очень то и очевидная). Но в любом случае благодарю за ответ.
0
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|
24.05.2018, 22:50 | 14 |
Сообщение было отмечено Undisputed как решение
Решение
Может, переводчики постарались? Текст под кодом намекает, что в коде не опечатка.
1
|
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
|
|
24.05.2018, 23:45 [ТС] | 15 |
rat0r,
Спасибо! Переводить тип возвращаемого значения это конечно сильно
0
|
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
|
|
25.05.2018, 11:57 | 16 |
Ух ты ж ё...
0
|
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
|
|
21.05.2019, 17:00 | 17 |
Но вообще это Мейерс решил, что лучше бы возвращался
DataType&&
Сообщение от https://www.aristeia.com/BookErrata/emc++-errata.html
0
|
1659 / 488 / 106
Регистрация: 17.05.2015
Сообщений: 1,497
|
||||||
21.05.2019, 20:34 | 18 | |||||
Как же вы так умыдрились получить одинаковый результат?
https://rextester.com/QFNOQ77094
Код
experiment #1... Widget: ctor ctor [1] return DataType&& Widget: dctor dtor done! experiment #2... Widget: ctor ctor [2] return DataType copy Widget: dctor dtor done! dtor experiment #3... Widget: ctor ctor [2] return move(m_values) Widget: dctor done! dtor experiment #4... Widget: ctor ctor done! Widget: dctor dtor Наглядно видно, что: 1. В первом случае получаем невалидную ссылку. Попытка использовать такую ссылку - ub 2. Во втором случае выполняется копия объекта. Не эффективно. 3. Мембер был перемещен во временный объект. время жизни временного объекта - до конца работы с итоговой ссылкой. 4. Итоговая ссылка продлила время жизни всего класса Widget С одной стороны это наиболее эффективный способ. С другой - компиляторы до сих пор не осилили эту часть стандарта. Можно запросто нарваться на протухшую ссылку. Итого: 3й вариант самый лучший: надежный и эффективный. (c) hoggy
сообщение скопировано с другого форума.
0
|
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
|
||||||
21.05.2019, 21:27 | 19 | |||||
Потому что rvalue-ссылка сама по себе ничего не делает. Делает конструктор/оператор переменной которой ты её присвоишь.
0
|
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
|
|
21.05.2019, 21:27 | 20 |
Методы, возвращающие &&-ссылки должны быть только кастами (каким является
std::move , например). А код в примере рано или поздно приведёт к UB.eva2326, пояснил довольно подробно. Возвращать std::move(x) стоит лишь если x — поле класса, в случае локальной переменной или аргумента сработает (N)RVO или move, т.к. результат функции, возвращённой по значению в любом случае является rvalue с точки зрения вызывающего кода.
0
|
21.05.2019, 21:27 | |
21.05.2019, 21:27 | |
Помогаю со студенческими работами здесь
20
Rvalue reference and lambda std::move, rvalue reference Rvalue reference. Что происходит в коде? что за возвращаемый тип, и как работает функция? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Опции темы | |
|
Новые блоги и статьи | |||||
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства
Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
|
Что такое NullReferenceException и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
|
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
|
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
|
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
|
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
|
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее:
На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
|
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript
В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
|
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
|
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален
В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
|
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
|
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели
В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
|