Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.63
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
#1

Move конструктор && - C++

28.11.2013, 11:38. Просмотров 2272. Ответов 13
Метки нет (Все метки)

Никак не могу понять, что же он делает. Вроде как пишут, что он даже предпочтительнее, чем всякие const MyType& var в качестве параметров в функции, но почему? Что же он на самом деле делает? Допустим, & в данном случае - просто обертка над указателем.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
12878 / 7264 / 810
Регистрация: 27.09.2012
Сообщений: 17,945
Записей в блоге: 2
Завершенные тесты: 1
28.11.2013, 11:45     Move конструктор && #2
блог пользователя soon: Семантика перемещения и perfect forwarding(правильная передача)
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
28.11.2013, 11:47     Move конструктор && #3
Цитата Сообщение от nexen Посмотреть сообщение
Вроде как пишут, что он даже предпочтительнее, чем всякие const MyType& var в качестве параметров в функции, но почему? Что же он на самом деле делает?
К rvalue reference "привязывается" временное значение, и т.к. это значение всё равно позже будет разрушено, то можно его переиспользовать - например в классе есть указатель на массив в куче, вместо его копирования в новый объект и уничтожения потом при разрушении временного можно просто поменять указатели. В случае с const& придётся делать копию.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.11.2013, 19:46  [ТС]     Move конструктор && #4
Croessmah, gray_fox, давно это было, когда я последний раз читал что-то и не понимал в прямом смысле ни слова.. Абсолютно.. Можно подробно для особо тупых?
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
29.11.2013, 20:15     Move конструктор && #5
nexen, относительно конструктора, с помощью && можно выделить случай, когда в качестве параметра передаётся временное значение; т.к. временное значение всё равно будет разрушено после, можно переиспользовать его ресурсы.

Добавлено через 1 минуту
Но это не касаясь шаблонов функций.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.11.2013, 20:33  [ТС]     Move конструктор && #6
gray_fox, что-то типа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct MyInteger
{
int x;
MyInteger(int &&number) //здесь передана ссылка на временный объект, который после завершения конструктора почти сразу умрет
{
x = number; //вместо того, чтобы вызывать конструктор X или оператор "=" (если бы Х было не int), просто number становится на место X, а сам Х уже освобождается. Таким образом вместо копирования + деструктора был вызван только деструктор.
}
};
/*
..
*/
int a = 10, b = 13;
MyInteger x(a * b); //создается временный объект (int)130
Правильно понял?
И, выходит, && имеет обратную совместимость с &? Т.е, вид:
MyInteger(const int& x)
будет равен
MyInteger(const int&& x), если параметр Х, переданный в конструктор, - не временный объект, так?

И как вообще const влияет на &&? Или не важно и спокойной в верхнем примере в структуре поле int x заменится на const int number через &&?

А с шаблонами что?
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
29.11.2013, 20:47     Move конструктор && #7
Цитата Сообщение от nexen Посмотреть сообщение
Правильно понял?
Примерно так, только относительно простых типов это смысла не имеет (в плане эффективности).
Вот такой пример:
C++
1
std::vector<> vector(std::vector<> {1, 2, 3});
Временный std::vector<> {1, 2, 3} после выполнения конструктора будет разрушен, но имея только конструктор копирования придётся всё равно делать его копию - а это лишняя работа, ведь можно просто поменять несколько указателей местами. Благодаря rvalue ref как раз и можно выделить такие случаи (когда аргумент временный) и с чистым сердцем проводить такие оптимизации.

Добавлено через 5 минут
Цитата Сообщение от nexen Посмотреть сообщение
И, выходит, && имеет обратную совместимость с &? Т.е, вид:
MyInteger(const int& x)
будет равен
MyInteger(const int&& x), если параметр Х, переданный в конструктор, - не временный объект, так?
эмм... не знаю, я не понял. К rvalue ref можно привязать только временное значение. Но можно иметь перегрузку:
C++
1
2
MyInteger(int const&);   // copy
MyInteger(int &&);   // move
Тогда при вызове с времменым значением будет вызван 2-й вариант, в остальных случаях - 1-й; т.е. можно различать когда агрумент lvalue, а когда - rvalue.

Добавлено через 3 минуты
Цитата Сообщение от nexen Посмотреть сообщение
А с шаблонами что?
С шаблонами там вступают "особые" правила вывода типов - reference collapsing rules, для поддержи perfect forwarding. Читали в блоге soon ?
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
29.11.2013, 21:16  [ТС]     Move конструктор && #8
gray_fox, как уже писал, читал, но ничего не понял. Теперь попробую прочитать снова
А что так с const int&&? Как такое вообще интерпретироваться будет? Или оное невозможно?

И кстати, && допустим только в конструкторе? Если нет, то что будет, если использовать оное в const методе? Позволит?
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
29.11.2013, 21:29     Move конструктор && #9
Цитата Сообщение от nexen Посмотреть сообщение
А что так с const int&&? Как такое вообще интерпретироваться будет? Или оное невозможно?
Вполне допустимо, но я лично не знаю применения.
Цитата Сообщение от nexen Посмотреть сообщение
И кстати, && допустим только в конструкторе?
Нет конечно, как и с обычными ссылками, где хотите, там и используйте. Констуктор для примера.

Не по теме:

Цитата Сообщение от nexen Посмотреть сообщение
gray_fox, как уже писал, читал, но ничего не понял.
Как мог и знаю, уж извини) Или это не ко мне? В любом случае...



Добавлено через 5 минут
Оснавная идея - теперь можно различать rvalue и lvalue в аргументах и вообще иметь ссылки на rvalue.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
30.11.2013, 08:05  [ТС]     Move конструктор && #10
gray_fox, меня вот беспокоит следующее. Предположим, за время действия программы мне нужно создать всего три объекта:
C++
1
2
3
4
int x = 1, y = 2, z = 3;
T a(x, y, z);
T b(x * y, y, z);
T c(x, y, z + y * 2);
(Использовал снова примитивы для простоты примера)
Так вот, раньше я бы использовал конструктор вида:
C++
1
T(const int& a, const int& b, const int& c);
Неужели теперь, если я хочу иметь код более оптимизированный, мне придется делать аж 3 конструктора? Отсюда и вопрос, если я имею конструктор:
C++
1
T(const int&& a, const int&& b, const int&& c);
и передаю параметры так:
C++
1
T d(x * y, y, z);
- сработает ли это? Будет ли &&, если передается не временный аргумент, интерпретироваться как & и этот ранее полностью move конструктор "превратится" в:
C++
1
T(const int&& a, const int& b, const int& c);
- об этой "обратной совместимости" я спрашивал. Или же если стоит &&, значит передавать можно только временный объект? Т.е., действительно, в данном простом примере уже нужно 3 конструктора, а в особо извращенных случаях это всё разрастется донельзя?

И да, кстати, чтобы параметр int&& param перекинуть в объект вместо поля int field мне достаточно сделать field = param? Или нужно какой-то там std::move использовать? (просто помню, что такое есть, но не знаю, зачем. Ещё раз блог soon не перечитывал ещё)
programina
30.11.2013, 08:39
  #11

Не по теме:

Интересная тема

gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
01.12.2013, 08:29     Move конструктор && #12
Цитата Сообщение от nexen Посмотреть сообщение
Отсюда и вопрос, если я имею конструктор:
Код C++
1
T(const int&& a, const int&& b, const int&& c);
и передаю параметры так:
Код C++
1
T d(x * y, y, z);
- сработает ли это?
Нет, т.к. y и z - lvalue.
Цитата Сообщение от nexen Посмотреть сообщение
Или же если стоит &&, значит передавать можно только временный объект?
Именно так.
Цитата Сообщение от nexen Посмотреть сообщение
И да, кстати, чтобы параметр int&& param перекинуть в объект вместо поля int field мне достаточно сделать field = param? Или нужно какой-то там std::move использовать?
Нужен move; вообще ссылка на rvalue - это lvalue.
C++
1
T(int && param) : field(std::move(param)) {}
Добавлено через 5 минут
Цитата Сообщение от nexen Посмотреть сообщение
Неужели теперь, если я хочу иметь код более оптимизированный, мне придется делать аж 3 конструктора?
Не 3, а больше - накаждую комбинацию const& и && ) Либо один шаблонный конструктор, навроде
C++
1
2
3
4
5
6
template<typename A, typename B, typename C>
T(A && a, B && b, C && c)
      : a(std::forward<A>(a))
      , b(std::forward<B>(b))
      , c(std::forward<C>(c))
      {}
Тогда если параметр lvalue (int), то имеем A && -> int & && -> int &. Если rvalue - то A && -> int &&.

Добавлено через 5 минут
Вот в описании std::forward аналогичный пример кстати: http://en.cppreference.com/w/cpp/utility/forward .
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
01.12.2013, 15:36  [ТС]     Move конструктор && #13
gray_fox, о-май-гад! Си все меньше и меньше походит на язык программирования для людей :|
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.12.2013, 15:41     Move конструктор &&
Еще ссылки по теме:

Почему в выражении нельзя использовать запятую вместо && C++
Nested classes && enum declaration C++
C++ Напишите цикл, эквивалентный приведенному выше циклу, не пользуясь операторами && и ||
C++ Strcpy_s выдает ошибку L Buffer is too small & & 0
C++ Вызвать функцию базового класса с ссылочным квалификатором &&

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
01.12.2013, 15:41     Move конструктор && #14
Цитата Сообщение от nexen Посмотреть сообщение
gray_fox, о-май-гад! Си все меньше и меньше походит на язык программирования для людей :|
Дык это ж не С) Тем более надо же было прикрутить всё это так, что бы не сломать всё остальное; и такие штуки не обязательно писать (если у вас там не либа какая "на все случаи жизни"), на практике NRVO наверняка решит все проблемы с лишними копиями.
Yandex
Объявления
01.12.2013, 15:41     Move конструктор &&
Ответ Создать тему
Опции темы

Текущее время: 01:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru