![Smile :)](./images/smilies/icon_smile.gif)
А был ли мальчик? (помянем плюсы)
-
- Уже с Приветом
- Posts: 5753
- Joined: 15 Aug 2008 00:52
Re: А был ли мальчик? (помянем плюсы)
который год уже с читаю АндреяТ на тему c++: понимаю, как мало я в этом деле понимаю ![Smile :)](./images/smilies/icon_smile.gif)
![Smile :)](./images/smilies/icon_smile.gif)
I would hope that a wise white man with the richness of his experiences would more often than not reach a better conclusion than a latina female who hasn't lived that life
-
- Уже с Приветом
- Posts: 15526
- Joined: 27 Sep 2007 22:53
Re: А был ли мальчик? (помянем плюсы)
Страуструп тоже об этом писал.Alexander Troyansky wrote: 26 Jan 2018 06:24 который год уже с читаю АндреяТ на тему c++: понимаю, как мало я в этом деле понимаю![]()
-
- Уже с Приветом
- Posts: 8090
- Joined: 08 Nov 2004 12:24
- Location: GA
Re: А был ли мальчик? (помянем плюсы)
Только если вижу как с большим апломбом и умным видом пишут глупости.Сабина wrote: 26 Jan 2018 05:45То есть вы не просто "страшный", вы еще и спорить любитеProsche wrote: 25 Jan 2018 16:08 Хорошо, хотите натягивать мув на свап, не смею вам мешать. Я сделал все что мог.
Хотите думать, что мув придуман чтобы сохранять дорогие ресурсы, барабан вам на шею. Будете сидеть в тишине вашего кабинета, попробуйте подумать почему именно мув, такое странное название, в словарик там посмотрите. Может быть осознаете простую истину, что идея мув в мув, взять справа и передвинуть влево, а совсем не сохранить "дорогие ресурсы".?
![Smile :-)](./images/smilies/smile.gif)
-
- Уже с Приветом
- Posts: 803
- Joined: 24 Jan 2007 07:32
- Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA
Re: А был ли мальчик? (помянем плюсы)
Вы почитайте книжки пожалуйста. Например Майерса - "Effective Modern C++"Prosche wrote: 26 Jan 2018 15:18Только если вижу как с большим апломбом и умным видом пишут глупости.Сабина wrote: 26 Jan 2018 05:45То есть вы не просто "страшный", вы еще и спорить любитеProsche wrote: 25 Jan 2018 16:08 Хорошо, хотите натягивать мув на свап, не смею вам мешать. Я сделал все что мог.
Хотите думать, что мув придуман чтобы сохранять дорогие ресурсы, барабан вам на шею. Будете сидеть в тишине вашего кабинета, попробуйте подумать почему именно мув, такое странное название, в словарик там посмотрите. Может быть осознаете простую истину, что идея мув в мув, взять справа и передвинуть влево, а совсем не сохранить "дорогие ресурсы".?
![]()
http://doc.imzlp.me/viewer.html?file=do ... ernCPP.pdf
Item 29 "Assume that move operations are not present,
not cheap, and not used." Page 203
Let’s begin with the observation that many types fail to support move semantics. The
entire C++98 Standard Library was overhauled for C++11 to add move operations
for types where moving could be implemented faster than copying,
Even types with explicit move support may not benefit as much as you’d hope. All
containers in the standard C++11 library support moving, for example, but it would
be a mistake to assume that moving all containers is cheap. For some containers, this
is because there’s no truly cheap way to move their contents. For others, it’s because
the truly cheap move operations the containers offer come with caveats the container
elements can’t satisfy.
Assuming that Widget is a type
where moving is faster than copying, moving a std::array of Widget will be faster
than copying the same std::array.
On the other hand, std::string offers constant-time moves and linear-time copies.
That makes it sound like moving is faster than copying,
Есть прямая связь между дорогими ресурсами и move семантикой.There are thus several scenarios in which C++11’s move semantics do you no good:
• No move operations: The object to be moved from fails to offer move opera‐
tions. The move request therefore becomes a copy request.
• Move not faster: The object to be moved from has move operations that are no
faster than its copy operations.
• Move not usable: The context in which the moving would take place requires a
move operation that emits no exceptions, but that operation isn’t declared noex
cept.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
-
- Уже с Приветом
- Posts: 8090
- Joined: 08 Nov 2004 12:24
- Location: GA
Re: А был ли мальчик? (помянем плюсы)
Капитан очевидность? Мув быстрее копирования? Неожиданно
![Smile :)](./images/smilies/icon_smile.gif)
![Very Happy :D](./images/smilies/biggrin.gif)
![Smile :-)](./images/smilies/smile.gif)
-
- Уже с Приветом
- Posts: 9195
- Joined: 04 Mar 2011 03:04
- Location: SFBA
Re: А был ли мальчик? (помянем плюсы)
Ну, как заставить компилятор сообщить о специфической ошибке невозможности использования стандартного контейнера? Как из того примера с vector<unique_ptr<T>>, где нет копирования и др. Если этого не сделать, gcc вываливает очень немалую кучку сообщений, пережевать которых ещё та работа.Medium-rare wrote: 25 Jan 2018 18:10 static_assert почаще применять для устранения недопониманий... Как в свой код поставить, понятно. А если хочется внятно сообщить о неправильном случае использования стандартного контейнера для конкретного типа?
... and even then it's rare that you'll be going there...
-
- Уже с Приветом
- Posts: 803
- Joined: 24 Jan 2007 07:32
- Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA
Re: А был ли мальчик? (помянем плюсы)
Вы написали вот это спорное утверждение на что я Вам и отвечал в предыдущем посте. Видимо мне это надо было подчеркнуть.Prosche wrote: 26 Jan 2018 18:35 мув в мув, взять справа и передвинуть влево, а совсем не сохранить "дорогие ресурсы"
Сохранить "дорогие ресурсы" - в этом и есть основной смысл move семантики, там где это быстрее копирования.
Вы обсуждали это не со мной а с AndreyT.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
-
- Уже с Приветом
- Posts: 8090
- Joined: 08 Nov 2004 12:24
- Location: GA
Re: А был ли мальчик? (помянем плюсы)
Понятно. Но в нем речь шла о том, чтобы сохранять дорогие ресурсы, вниманиеPantigalt wrote: 26 Jan 2018 19:08 Вы написали вот это спорное утверждение на что я Вам и отвечал в предыдущем посте. Видимо мне это надо было подчеркнуть.
Сохранить "дорогие ресурсы" - в этом и есть основной смысл move семантики, там где это быстрее копирования.
![Mentor :umnik1:](./images/smilies/umnik.gif)
-
- Уже с Приветом
- Posts: 803
- Joined: 24 Jan 2007 07:32
- Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA
Re: А был ли мальчик? (помянем плюсы)
Кстати если кому интересно вот решил заглянуть как имплементирован std::swap и std::move в Visual Studio 2017
std::swap
std::swap
std::movetemplate<class _Ty,
class> inline
void swap(_Ty& _Left, _Ty& _Right)
_NOEXCEPT_COND(is_nothrow_move_constructible<_Ty>::value
&& is_nothrow_move_assignable<_Ty>::value)
{ // exchange values stored at _Left and _Right
_Ty _Tmp = _STD move(_Left);
_Left = _STD move(_Right);
_Right = _STD move(_Tmp);
}
// TEMPLATE FUNCTION move
template<class _Ty>
constexpr remove_reference_t<_Ty>&&
move(_Ty&& _Arg) _NOEXCEPT
{ // forward _Arg as movable
return (static_cast<remove_reference_t<_Ty>&&>(_Arg));
}
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
-
- Уже с Приветом
- Posts: 3003
- Joined: 14 Apr 2004 01:11
- Location: SFBA (было: Минск, Беларусь)
Re: А был ли мальчик? (помянем плюсы)
Не совсем понятно, что именно вы хотели увидеть. Это довольно странная комбинация, ибо `std::swap` и `std::move` - совершенно разные по своей природе сущности. Как пара из яблока и апел^H^H^H логарифмической линейки.Pantigalt wrote: 26 Jan 2018 19:45 Кстати если кому интересно вот решил заглянуть как имплементирован std::swap и std::move в Visual Studio 2017
`std::swap` - это алгоритм физически реализующий операцию обмена значений.
`std::move` же физически не делает ничего вообще. Он не реализует никакой операции move. `std::move` - это просто другая форма записи явного каста к типу rvalue reference. А собственно физическое перемещение данных вы должны реализовывать сами, руками в той функции, которая вызовется для аргумента типа rvalue reference, полученного из `std::move`.
Строго говоря `std::move` "не нужен" - вы можете им вообще не пользоваться, а просто везде явно руками выполнять `static_cast` к типу rvalue reference (т.е. имено то, что вы увидели внутри реализации `std::move`). Но `std::move` ввели в качестве альтернативной формы записи для этого `static_cast` - просто чтобы повысить удобочитаемость и компактность кода.
---
Может быть вы и не имели это в виду, но это довольно распространненая ошибка: полагать что, мол, "`std::swap` реализует swap, а `std::move` реализует move". На самом же деле `std::swap` действительно реализует swap, а вот `std::move` не реализует ничего вообще.
Best regards,
Андрей
Андрей
-
- Уже с Приветом
- Posts: 803
- Joined: 24 Jan 2007 07:32
- Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA
Re: А был ли мальчик? (помянем плюсы)
Про то что std::move физически ничего не перемещает мне известно.AndreyT wrote: 26 Jan 2018 20:11Не совсем понятно, что именно вы хотели увидеть. Это довольно странная комбинация, ибо `std::swap` и `std::move` - совершенно разные по своей природе сущности. Как пара из яблока и апел^H^H^H логарифмической линейки.Pantigalt wrote: 26 Jan 2018 19:45 Кстати если кому интересно вот решил заглянуть как имплементирован std::swap и std::move в Visual Studio 2017
`std::swap` - это алгоритм физически реализующий операцию обмена значений.
`std::move` же физически не делает ничего вообще. Он не реализует никакой операции move. `std::move` - это просто другая форма записи явного каста к типу rvalue reference. А собственно физическое перемещение данных вы должны реализовывать сами, руками в той функции, которая вызовется для аргумента типа rvalue reference, полученного из `std::move`.
Строго говоря `std::move` "не нужен" - вы можете им вообще не пользоваться, а просто везде явно руками выполнять `static_cast` к типу rvalue reference (т.е. имено то, что вы увидели внутри реализации `std::move`). Но `std::move` ввели в качестве альтернативной формы записи для этого `static_cast` - просто чтобы повысить удобочитаемость и компактность кода.
---
Может быть вы и не имели это в виду, но это довольно распространненая ошибка: полагать что, мол, "`std::swap` реализует swap, а `std::move` реализует move". На самом же деле `std::swap` действительно реализует swap, а вот `std::move` не реализует ничего вообще.
Я обратил внимание на другое - на move assignment.
Я как то об этом не думал что в операции swap логичнее использовать move assignment вместо copy assignment.
Хотя вроде это и очевидно.
На самом деле у меня мало практического опыта на С++ так что не удивляйтесь что какие то вещи очевидные вам не сразу очевидны мне.
Моя основная специализация C# хотя я читал много книг по C++ в свое время.
PS: К слову об очевидных вещах. В вышеприведенной реализации с 3-мя move. В первом случае для аргумента будет вызван move конструктор a для остальных move assignment.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
-
- Уже с Приветом
- Posts: 803
- Joined: 24 Jan 2007 07:32
- Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA
Re: А был ли мальчик? (помянем плюсы)
Я с Вами немного подискутирую тут.AndreyT wrote: 26 Jan 2018 20:40 Строго говоря `std::move` "не нужен" - вы можете им вообще не пользоваться, а просто везде явно руками выполнять `static_cast` к типу rvalue reference (т.е. имено то, что вы увидели внутри реализации `std::move`). Но `std::move` ввели в качестве альтернативной формы записи для этого `static_cast` - просто чтобы повысить удобочитаемость и компактность кода.
Вы все верно сказали про то что
1. Можно явно руками выполнять `static_cast` к типу rvalue reference
2. `std::move` ввели в качестве альтернативной формы записи для этого `static_cast` - просто чтобы повысить удобочитаемость и компактность кода
Как я вижу move там оказался еще и потому что передает смысл намерений (хотя при std::move физически ничего не происходит кроме каста).
"Внимание!!! Сейчас обьект будет перемещен (будет вызван move constructor или move assignments и обьект будет передан как аргумент)."
1. Создали новый временный обьект в который "переместили" содержимое первого параметра.
2. В первый (уже пустой) обьект "переместили" содержимое второго параметра.
3. Во второй (уже пустой) обьект "переместили" содержимое временного обьекта.
Сравним это со "старым стилем".
1. Создали новый временный обьект в который "скопировали" содержимое первого параметра.
2. В первый (не пустой) обьект "скопировали" содержимое второго параметра.
3. Во второй (не пустой) обьект "скопировали" содержимое временного обьекта.
В общем виде не было возможности реализовать эффективный swap.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
-
- Уже с Приветом
- Posts: 15526
- Joined: 27 Sep 2007 22:53
Re: А был ли мальчик? (помянем плюсы)
Вполне себе нормальная практика имплементировать конструктор копирования && и оператор присваивания && через swap.
-
- Уже с Приветом
- Posts: 8090
- Joined: 08 Nov 2004 12:24
- Location: GA
Re: А был ли мальчик? (помянем плюсы)
Ничего не могу ответить, на моменте представленном выше у меня мозг ушел в холодный рестарт.
-
- Уже с Приветом
- Posts: 15526
- Joined: 27 Sep 2007 22:53
Re: А был ли мальчик? (помянем плюсы)
Конструктор переноса и оператор перемещающего присваивания. ЛоханулсяProsche wrote: 27 Jan 2018 01:01 Ничего не могу ответить, на моменте представленном выше у меня мозг ушел в холодный рестарт.
Вот в этом примере с помощью свопа реализовано одновременно и копирующее и перемещающее присваивание.
Разумеется при наличии обеих форм конструктора копирования.
Class A {
A& operator=(A source) {
swap(*this, source);
return *this;
}
....
}