Перемещающее присваивание в STL
От: LaptevVV Россия  
Дата: 08.11.15 11:17
Оценка: -2
Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?
У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
v1 = v2; // -- и что?
Или надо писать явно?
v1 = move(v2);
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Перемещающее присваивание в STL
От: _NN_ www.nemerleweb.com
Дата: 08.11.15 11:56
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?

LVV>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>v1 = v2; // -- и что?
LVV>Или надо писать явно?
Логично ведь , не ?
LVV>v1 = move(v2);


vector<int> v1,v2;
v1 = v2; // тут operator=(vector<int> const&), который копирует

v1 = move(v2); // тут уже operator=(vector<int>&&) , который перемещает
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Перемещающее присваивание в STL
От: Zhendos  
Дата: 08.11.15 12:06
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?

LVV>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>v1 = v2; // -- и что?

operator=(const vector&)



LVV>Или надо писать явно?


LVV>v1 = std::move(v2);


А вот здесь будет
operator=(vector&&)


А вот в таком коде будет неявный move:

std::vector<int> f()
{
  return std::vector<int>{1, 2};
}
v1 = f();
Re: Перемещающее присваивание в STL
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 08.11.15 12:10
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?

LVV>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>v1 = v2; // -- и что?
LVV>Или надо писать явно?
LVV>v1 = move(v2);

Перемещающее присваивание используется для присваивания rvalue — временного значения или результата функции, возвращающей rvalue reference. move является одной такой функцией.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: Перемещающее присваивание в STL
От: LaptevVV Россия  
Дата: 08.11.15 12:30
Оценка: -3
LVV>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?
LVV>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>>v1 = v2; // -- и что?
LVV>>Или надо писать явно?
_NN>Логично ведь , не ?
LVV>>v1 = move(v2);
Нифига не логично...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Перемещающее присваивание в STL
От: Zhendos  
Дата: 08.11.15 12:47
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?

LVV>>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>>>v1 = v2; // -- и что?
LVV>>>Или надо писать явно?
_NN>>Логично ведь , не ?
LVV>>>v1 = move(v2);
LVV>Нифига не логично...

Надо рассматривать с точки зрения преемственности.
Сначала были оператор копирования и
конструктор копирования, соотвественно семантика
v1 = v2;
давно известна и никто ее ломать
в новом 1y стандарте не будет, стандарты же стараются
делать совместимыми в обратную сторону.
Если бы здесь вызывался оператор перемещающего копирования,
то v2 стал бы пустым после этого, что сломало бы кучу программ.
Re[4]: Перемещающее присваивание в STL
От: LaptevVV Россия  
Дата: 08.11.15 13:09
Оценка:
_NN>>>Логично ведь , не ?
LVV>>>>v1 = move(v2);
LVV>>Нифига не логично...

Z>семантика
v1 = v2;
давно известна и никто ее ломать

Z>в новом 1y стандарте не будет, стандарты же стараются
Z>делать совместимыми в обратную сторону.
Z>Если бы здесь вызывался оператор перемещающего копирования,
Z>то v2 стал бы пустым после этого, что сломало бы кучу программ.
Да это все понятно.
У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.
А прописано следующее:
c = rv

И написано: Перемещающее присваивание всех элементов из вектора rv в вектор с (по стандарту С++11)
Опечатка?
Поэтому, собственно, и возник вопрос.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Перемещающее присваивание в STL
От: Шахтер Интернет  
Дата: 08.11.15 13:11
Оценка: +2
Здравствуйте, LaptevVV, Вы писали:

LVV>>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?

LVV>>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
LVV>>>v1 = v2; // -- и что?
LVV>>>Или надо писать явно?
_NN>>Логично ведь , не ?
LVV>>>v1 = move(v2);
LVV>Нифига не логично...

Перемещение разрушает исходный объект, поэтому:

1) должно быть явно выраженным в коде,
2) не должно использоваться неявно (за несколькими исключениями).

Иначе это неприятный источник ошибок.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Перемещающее присваивание в STL
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 08.11.15 13:20
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Да это все понятно.

LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.
LVV>А прописано следующее:
LVV>
c = rv

LVV>И написано: Перемещающее присваивание всех элементов из вектора rv в вектор с (по стандарту С++11)
LVV>Опечатка?
LVV>Поэтому, собственно, и возник вопрос.

rv — это не произвольный vector, а rvalue.
Ce n'est que pour vous dire ce que je vous dis.
Re[5]: Перемещающее присваивание в STL
От: Evgeny.Panasyuk Россия  
Дата: 08.11.15 13:21
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.

LVV>А прописано следующее:
LVV>
c = rv

LVV>И написано: Перемещающее присваивание всех элементов из вектора rv в вектор с (по стандарту С++11)
LVV>Опечатка?
LVV>Поэтому, собственно, и возник вопрос.

rv — это видимо сокращение от rvalue, а не от rvector
Re[3]: Перемещающее присваивание в STL
От: Ops Россия  
Дата: 08.11.15 13:31
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Нифига не логично...


Если к правой части можно обратиться по имени, то будет копирование, если нельзя, то перемещение.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Перемещающее присваивание в STL
От: _NN_ www.nemerleweb.com
Дата: 08.11.15 13:45
Оценка:
Здравствуйте, LaptevVV, Вы писали:

Тут уже на всё ответили.
Добавлю, что в итоге всё зависит конечно от того как реализует сам класс.
Например можно в стиле auto_ptr реализовать operator=(auto_ptr&) который будет разрушать неявно объект справа.
Можно запретить операции копирования вообще и разрешить только operator=(&&) как делает unique_ptr.
А можно определить всё сразу как делает vector, в этом случае тем более стоит выделять явно , компилятор то мысли не читает
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Перемещающее присваивание в STL
От: LaptevVV Россия  
Дата: 08.11.15 13:49
Оценка:
_NN>Добавлю, что в итоге всё зависит конечно от того как реализует сам класс.
Не, не надо. Сам класс я сам могу написать, как требуется...
Меня конкретно интересовало, почему у Джосатиса не прописано явно move().
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Перемещающее присваивание в STL
От: T4r4sB Россия  
Дата: 08.11.15 14:38
Оценка: -1
Здравствуйте, Шахтер, Вы писали:

Ш>Перемещение разрушает исходный объект, поэтому:


Ш>1) должно быть явно выраженным в коде,

Ш>2) не должно использоваться неявно (за несколькими исключениями).

Ш>Иначе это неприятный источник ошибок.


Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет. Сам же объект остаётся в самосогласованном состоянии, к нему можно обращаться, с ним можно работать, а ещё у него обязательно вызовется деструктор после всего этого.
Если бы перемещение действительно разрушало объект (в смысле — приводило бы к состоянию, после которого к нему нельзя обращаться ни в каком виде), то было бы всё наоборот, чем ты сказал:

1. перемещать вручную было бы так же опасно, как вызывать деструктор вручную
2. оно бы вызывалось автоматически, если бы компилятор видел, что это последнее использование объекта в зоне видимости, причём вызывалось бы оно вместо деструктора (вернее, вместо пары "копирование-деструктор").

Пример перемещения как оно сейчас есть:

ptr (ptr&& other)
{
  this.v = other.v;
  other.v = NULL;
}

~ptr ()
{
  if (V)
    delete v;
}


Если бы перемещение действительно было разрушающим в некоей альтернативной вселенной, было бы так:


ptr (ptr&& other)
{
  this.v = other.v;
// а занулять не надо - other уже никому не нужен, и даже деструктор его не вызовется
}

~ptr ()
{
// а проверять не надо
  delete v;
}
Re[5]: Перемещающее присваивание в STL
От: flаt  
Дата: 08.11.15 17:45
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.

А можно ссылку на страницу или скриншот? Наверняка, у таблицы определения переменных.
Re[6]: Перемещающее присваивание в STL
От: LaptevVV Россия  
Дата: 08.11.15 19:10
Оценка:
LVV>>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.
F>А можно ссылку на страницу или скриншот? Наверняка, у таблицы определения переменных.
Не. Как раз у таблиц — никаких определений переменных нет...
Семантика перемещения и rvalue-ссылки у него описаны в разделе 3.1.5 на стр. 43-48.
Там тоже написано о реализации, а не о конкретных контейнерах.
О move() — упомянуто.
Еще о семантике копирования и перемещения сказано в разделе 6.11 — Элементы контейнера.
Еще перемещающее присваивание прописано в общей таблице 7.1.
И тоже в таком же виде: c = rv;
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[5]: Перемещающее присваивание в STL
От: Шахтер Интернет  
Дата: 08.11.15 20:31
Оценка: -1
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Шахтер, Вы писали:


Ш>>Перемещение разрушает исходный объект, поэтому:


Ш>>1) должно быть явно выраженным в коде,

Ш>>2) не должно использоваться неявно (за несколькими исключениями).

Ш>>Иначе это неприятный источник ошибок.


TB>Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет.


Разрушает. После перемещения исходный объект меняет состояние.

TB>Сам же объект остаётся в самосогласованном состоянии, к нему можно обращаться, с ним можно работать, а ещё у него обязательно вызовется деструктор после всего этого.


Это не важно. Важно то, что объект неузнаваемым образом изменился.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: Перемещающее присваивание в STL
От: watchyourinfo Аргентина  
Дата: 08.11.15 21:08
Оценка: +3
TB>>Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет.

Ш>Разрушает. После перемещения исходный объект меняет состояние.


Подозреваю, что у вас терминологическая путаница.
"Разрушает" это прямой перевод слова "destroy", что в контексте стандарта С++ имеет специфическое недвусмысленное значение, эквивалентное вызову деструктора.

(и конечно объект не является разрушенным в этом смысле после перемещения)
Отредактировано 08.11.2015 21:13 watchyourinfo . Предыдущая версия .
Re: Перемещающее присваивание в STL
От: Vamp Россия  
Дата: 08.11.15 23:25
Оценка: 1 (1)
LVV>v1 = move(v2);
Можно еще вот так:
v1 = static_cast<decltype(v2)&&>(v2);

Тоже move будет.
Да здравствует мыло душистое и веревка пушистая.
Отредактировано 08.11.2015 23:26 Vamp . Предыдущая версия .
Re: Перемещающее присваивание в STL
От: jazzer Россия Skype: enerjazzer
Дата: 09.11.15 00:41
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?


А как отличить копирующее конструирование от перемещающего?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.