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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.63
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
28.11.2013, 11:38     Move конструктор && #1
Никак не могу понять, что же он делает. Вроде как пишут, что он даже предпочтительнее, чем всякие const MyType& var в качестве параметров в функции, но почему? Что же он на самом деле делает? Допустим, & в данном случае - просто обертка над указателем.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.11.2013, 11:38     Move конструктор &&
Посмотрите здесь:

Проблема с проверкой условия цикла for( int i=2; !((n%i||d%i)&&!(n%i&&d%i))==0 ; i++) C++
В заштрихованную фигуру бросают точки с координатами x и y. Получить координаты первой точки не попавшей в эту область (фигура x*x+y*y<25&&x*x+y*y>=9& C++
C++ Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
C++ C++ 11 конструктор переноса &&
В программе объявлена переменная int x=1; определить значение выражения х>0 && x<1 ? 10/x : 10*x C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11825 / 6804 / 769
Регистрация: 27.09.2012
Сообщений: 16,871
Записей в блоге: 2
Завершенные тесты: 1
28.11.2013, 11:45     Move конструктор && #2
блог пользователя soon: Семантика перемещения и perfect forwarding(правильная передача)
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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 конструктор &&
Еще ссылки по теме:

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка? C++
Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) C++
Friend ostream& operator<<(ostream& stream, CArr& obj); C++

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

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

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