Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего?
У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор).
v1 = v2; // -- и что?
Или надо писать явно?
v1 = move(v2);
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, 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>&&) , который перемещает
Здравствуйте, LaptevVV, Вы писали:
LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего? LVV>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор). LVV>v1 = v2; // -- и что?
Здравствуйте, LaptevVV, Вы писали:
LVV>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего? LVV>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор). LVV>v1 = v2; // -- и что? LVV>Или надо писать явно? LVV>v1 = move(v2);
Перемещающее присваивание используется для присваивания rvalue — временного значения или результата функции, возвращающей rvalue reference. move является одной такой функцией.
LVV>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего? LVV>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор). LVV>>v1 = v2; // -- и что? LVV>>Или надо писать явно? _NN>Логично ведь , не ? LVV>>v1 = move(v2);
Нифига не логично...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего? LVV>>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор). LVV>>>v1 = v2; // -- и что? LVV>>>Или надо писать явно? _NN>>Логично ведь , не ? LVV>>>v1 = move(v2); LVV>Нифига не логично...
Надо рассматривать с точки зрения преемственности.
Сначала были оператор копирования и
конструктор копирования, соотвественно семантика
v1 = v2;
давно известна и никто ее ломать
в новом 1y стандарте не будет, стандарты же стараются
делать совместимыми в обратную сторону.
Если бы здесь вызывался оператор перемещающего копирования,
то v2 стал бы пустым после этого, что сломало бы кучу программ.
_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)
Опечатка?
Поэтому, собственно, и возник вопрос.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Если у меня есть два вектора v1, v2, то как отличить копирующее присваивание от перемещающего? LVV>>>У джоссатиса об этом как-то не очень ясно написано (или я просто не нашел, где он об этом пишет конкретно про вектор). LVV>>>v1 = v2; // -- и что? LVV>>>Или надо писать явно? _NN>>Логично ведь , не ? LVV>>>v1 = move(v2); LVV>Нифига не логично...
Перемещение разрушает исходный объект, поэтому:
1) должно быть явно выраженным в коде,
2) не должно использоваться неявно (за несколькими исключениями).
Здравствуйте, LaptevVV, Вы писали:
LVV>Да это все понятно. LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано. LVV>А прописано следующее: LVV>
c = rv
LVV>И написано: Перемещающее присваивание всех элементов из вектора rv в вектор с (по стандарту С++11) LVV>Опечатка? LVV>Поэтому, собственно, и возник вопрос.
Здравствуйте, LaptevVV, Вы писали:
LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано. LVV>А прописано следующее: LVV>
c = rv
LVV>И написано: Перемещающее присваивание всех элементов из вектора rv в вектор с (по стандарту С++11) LVV>Опечатка? LVV>Поэтому, собственно, и возник вопрос.
rv — это видимо сокращение от rvalue, а не от rvector
Тут уже на всё ответили.
Добавлю, что в итоге всё зависит конечно от того как реализует сам класс.
Например можно в стиле auto_ptr реализовать operator=(auto_ptr&) который будет разрушать неявно объект справа.
Можно запретить операции копирования вообще и разрешить только operator=(&&) как делает unique_ptr.
А можно определить всё сразу как делает vector, в этом случае тем более стоит выделять явно , компилятор то мысли не читает
_NN>Добавлю, что в итоге всё зависит конечно от того как реализует сам класс.
Не, не надо. Сам класс я сам могу написать, как требуется...
Меня конкретно интересовало, почему у Джосатиса не прописано явно move().
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Шахтер, Вы писали:
Ш>Перемещение разрушает исходный объект, поэтому:
Ш>1) должно быть явно выраженным в коде, Ш>2) не должно использоваться неявно (за несколькими исключениями).
Ш>Иначе это неприятный источник ошибок.
Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет. Сам же объект остаётся в самосогласованном состоянии, к нему можно обращаться, с ним можно работать, а ещё у него обязательно вызовется деструктор после всего этого.
Если бы перемещение действительно разрушало объект (в смысле — приводило бы к состоянию, после которого к нему нельзя обращаться ни в каком виде), то было бы всё наоборот, чем ты сказал:
1. перемещать вручную было бы так же опасно, как вызывать деструктор вручную
2. оно бы вызывалось автоматически, если бы компилятор видел, что это последнее использование объекта в зоне видимости, причём вызывалось бы оно вместо деструктора (вернее, вместо пары "копирование-деструктор").
Если бы перемещение действительно было разрушающим в некоей альтернативной вселенной, было бы так:
ptr (ptr&& other)
{
this.v = other.v;
// а занулять не надо - other уже никому не нужен, и даже деструктор его не вызовется
}
~ptr ()
{
// а проверять не надо
delete v;
}
Здравствуйте, LaptevVV, Вы писали:
LVV>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано.
А можно ссылку на страницу или скриншот? Наверняка, у таблицы определения переменных.
LVV>>У Джоссатиса в таблице 7.9 (стр. 303-304) и в таблице 7.11 (стр. 305) move() конкретно не прописано. F>А можно ссылку на страницу или скриншот? Наверняка, у таблицы определения переменных.
Не. Как раз у таблиц — никаких определений переменных нет...
Семантика перемещения и rvalue-ссылки у него описаны в разделе 3.1.5 на стр. 43-48.
Там тоже написано о реализации, а не о конкретных контейнерах.
О move() — упомянуто.
Еще о семантике копирования и перемещения сказано в разделе 6.11 — Элементы контейнера.
Еще перемещающее присваивание прописано в общей таблице 7.1.
И тоже в таком же виде: c = rv;
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, Шахтер, Вы писали:
Ш>>Перемещение разрушает исходный объект, поэтому:
Ш>>1) должно быть явно выраженным в коде, Ш>>2) не должно использоваться неявно (за несколькими исключениями).
Ш>>Иначе это неприятный источник ошибок.
TB>Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет.
Разрушает. После перемещения исходный объект меняет состояние.
TB>Сам же объект остаётся в самосогласованном состоянии, к нему можно обращаться, с ним можно работать, а ещё у него обязательно вызовется деструктор после всего этого.
Это не важно. Важно то, что объект неузнаваемым образом изменился.
TB>>Перемещение не разрушает исходный объект, оно лишь лишает его ресурса, которым он владеет.
Ш>Разрушает. После перемещения исходный объект меняет состояние.
Подозреваю, что у вас терминологическая путаница.
"Разрушает" это прямой перевод слова "destroy", что в контексте стандарта С++ имеет специфическое недвусмысленное значение, эквивалентное вызову деструктора.
(и конечно объект не является разрушенным в этом смысле после перемещения)