Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, Коваленко Дмитрий, Вы писали:
КД>>Лично я определяю SetB(B&& b) только в довесок к нормальному "void SetB(const B& b)" U>а для чего это надо? почему нельзя было обойтись одним методом, принимающим аргумент по значению? U>void SetB(B b); U>я могу себе еще такое представить, когда два метода определяются в шаблонных классах, ибо они могут работать как с movable, так и не с movable классами (хотя тут тоже есть о чем кумекать)
Потому что представь, что твой В — это тяжелый std::vector.
Здравствуйте, jazzer, Вы писали:
J>Потому что представь, что твой В — это тяжелый std::vector.
ну прямо под землю провалимся от его веса
если клиент захочет отдать объект, он передаст владение через вызов SetB(std::move(b));
если не захочет — то передаст копию SetB(b);
Re[4]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, uzhas, Вы писали:
U>научите готовить
сомневаюсь что моё дилетантское мнение кому-то интересно, но тем не менее:
U>1) люди начинают их впихивать туда, где передача по значению была бы приемлемой (тут можете меня поучить)
class A
{
public:
//я чего-то не понимаю или тут реально не нужно && ? ведь это ненужное ограничение на клиентаvoid SetB(B&& b)
{
m_b = std::move(b);
}
B m_b;
};
т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам. что касается случая с передачей по значению, то тут лучше вообще не использовать ни замещение ни дополнение:
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, jazzer, Вы писали:
J>>Потому что представь, что твой В — это тяжелый std::vector. U>ну прямо под землю провалимся от его веса U>если клиент захочет отдать объект, он передаст владение через вызов SetB(std::move(b)); U>если не захочет — то передаст копию SetB(b);
Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой
Обычно предпочитают делать на вызываемой, чтоб облегчить клиентский код, чтоб клиенту не надо было все время писать std::move (более того, тебе его тоже придется написать, когда будешь присваивать).
Здравствуйте, о_О, Вы писали:
о_О>т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам.
возможно, вас сбило слово "впихивать", поэтому вы подсчитали, что что-то наращивается
представим, что класс A пишется с нуля
какую сигнатуру для SetB вы порекомендуете?
U>>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator=
о_О>т.к. мы можем принять временный объект, а можем переместить один объект в другой, реализация A::operator=(B&& b) должна быть следующей: о_О>
о_О> - освобождение ресурсов A
о_О> - перемещение ресурсов B в A
о_О>
о_О>а вот как вы это реализуете, уже не имеет значения. смысл лишь в том, чтобы объект A был чист перед перемещением, а объект B после перемещения.
ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )
из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3
если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще
если бы std::move не превращал нормальные объекты во "временные", то можно было бы делать банальный swap (variant 2), а так как новый стандарт разрешает корежить\портить нормальные объекты, то приходится изголяться, как в variant 3, что неблаготворно сказывается на качестве кода
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, jazzer, Вы писали:
J>Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой
казалось бы палка о двух концах, но я так не считаю
напомню о чем я говорю, чтобы мы говорили об одном и том же:
SetB(B&&) с точки зрения дизайна вносит необоснованное ограничение (невозможность подставить lvalue) ради некоторой оптимизации
SetB(B b) не имеет такого ограничения и тоже позволяет применить оптимизацию
так вот:
1) не все вектора тяжелые
2) класс чаще всего может работать как я тяжелыми так и с легкими векторами, как следствие, решение тяжелый вектор или нет вполне логично принять на клиентской стороне
3) нет такой best-practice передавать владения векторов, вектор как тип нетяжелый, тяжелым он может быть лишь в некоторых случаях в рантайме
J>Обычно предпочитают делать на вызываемой, чтоб облегчить клиентский код, чтоб клиенту не надо было все время писать std::move (более того, тебе его тоже придется написать, когда будешь присваивать).
в реальности облегчения скорее всего не будет, т.к. клиенту все равно надо будет писать std::move, если у него lvalue
весь вопрос в том, должен ли его заставить это сделать метод SetB или же предоставить клиенту выбор
если выбора нет, то передать копию клиенту придется так:
B b;
SetB(B(b));
//work with b
Re[6]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, о_О, Вы писали:
о_О>>т.к. && обладают другой семантикой по сравнению с обычными &, использовать && вместо чего-то не нужно. && нужно дополнять к уже имеющимся методам. U>возможно, вас сбило слово "впихивать", поэтому вы подсчитали, что что-то наращивается U>представим, что класс A пишется с нуля U>какую сигнатуру для SetB вы порекомендуете?
по значению
U>>>2) из-за того что std::move может превратить нормальный (lvalue) объект в rvalue&& не совсем ясно (холиворно) приходится имплементить move-operator=
о_О>>т.к. мы можем принять временный объект, а можем переместить один объект в другой, реализация A::operator=(B&& b) должна быть следующей: о_О>>
о_О>> - освобождение ресурсов A
о_О>> - перемещение ресурсов B в A
о_О>>
о_О>>а вот как вы это реализуете, уже не имеет значения. смысл лишь в том, чтобы объект A был чист перед перемещением, а объект B после перемещения. U>ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )
почему?)
U>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3
вариант 2 вообще неверен, остались 1 и 3.
U>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще
у GCC вариант 1
U>если бы std::move не превращал нормальные объекты во "временные", то можно было бы делать банальный swap (variant 2), а так как новый стандарт разрешает корежить\портить нормальные объекты, то приходится изголяться, как в variant 3, что неблаготворно сказывается на качестве кода
для простых типов возможен только вариант 1. итого 2 разные реализации == ни есть гут
и вообще. у vc++ 3й, у gcc 1й; у меня, 1й у вас 3й -- быдлан какой-то
Re[7]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, о_О, Вы писали:
U>>какую сигнатуру для SetB вы порекомендуете?
о_О>по значению
вот и у меня такое же мнение
U>>ваше мнение понятно и оно вполне логично, только не у всех оно укладывается в голове (в частности у меня )
о_О>почему?)
да напрягает как-то освобождать сви ресурсы
вместо того, чтобы всю деструктивную логику держать в деструкторе, мне приходится делать функцию CloseAll() и вызывать ее из деструктора и из operator=(A&&) U>>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3
о_О>вариант 2 вообще неверен, остались 1 и 3.
виноват, забыл return, основная идея этого варианта в банальном swap-е
U>>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще
о_О>у GCC вариант 1
опачки, это интересно
о_О>и вообще. у vc++ 3й, у gcc 1й; у меня, 1й у вас 3й -- быдлан какой-то
я был бы рад, если бы вариант 2 был приемлем )) уж очень он простой )))
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, о_О, Вы писали:
U>>>какую сигнатуру для SetB вы порекомендуете?
о_О>>по значению
U>вот и у меня такое же мнение
всё верно. и вы уже сами объяснили почему
U>>>из предложенных вариантов вы приняли variant 1 и посчитали неприемлемыми 2, 3 о_О>>вариант 2 вообще неверен, остались 1 и 3. U>виноват, забыл return, основная идея этого варианта в банальном swap-е
я и не заметил про return
я когда в свой умный указатель для COM объедков прикручивал && вначале так и написал — swap(). потом подумал и понял, что fail. далее я долго маялся — как же делать — вариант 1 или 3. т.к. я помешан на читаемости кода, решил что 1
U>>>если посмотреть на реализацию подобных операторов в стандартной либе VS2010, то можно заметить прием, который реализован в variant 3, а это заставляет подумать еще
о_О>>у GCC вариант 1 U>опачки, это интересно
stl в vs 2010 кривая. вон у shared_ptr нельзя явно инстанцировать экземпляр, т.к. они вместо _Swap написали swap
вот тут если не ошибаюсь:
Здравствуйте, Masterkent, Вы писали:
M>Ну и неплохо было бы напомнить о существовании 4-го варианта:
M>
A &operator=(A &&) noexcept = default;
M>Добиться, чтобы это сработало, во многих случаях не так уж и сложно. Заодно не нужно будет думать о реализации функции swap (std::swap вполне хватит).
каюсь, про defaulted, deleted ещё не читал
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, Masterkent, Вы писали:
M>о_О:
о_О>>вариант 2 вообще неверен, остались 1 и 3.
M>Вариант 2 вполне может быть верным, тут всё зависит от требований к состоянию moved from объекта в каждом конкретном случае.
M>Ну и неплохо было бы напомнить о существовании 4-го варианта:
M>
A &operator=(A &&) noexcept = default;
M>Добиться, чтобы это сработало, во многих случаях не так уж и сложно. Заодно не нужно будет думать о реализации функции swap (std::swap вполне хватит).
можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат. Можно просто ссылки на код, можно на группы/обсуждения. Хоть что нибудь, пожалуйста.
зы я обеими ногами за #include <thread> и все что с ним связано, но пока выглядит этот новый язык как мутный головняк.
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, SleepyDrago, Вы писали:
SD>можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат. Можно просто ссылки на код, можно на группы/обсуждения. Хоть что нибудь, пожалуйста.
Да вот хотя бы примитивный тест:
1М элементов
sort для vector<string> — 1.852954 sec, дофигища копирований
sort для vector<string>, string c поддержкой move constructor/operator — 0.532721 sec, ни одного копирования
Разница в 3.478280 раза
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, SleepyDrago, Вы писали:
SD>можно у вас, как эксперта приближенного к процессу стандартизации, спросить ссылок на то какую проблему эта вся синтаксическая карусель с rvalue решила? То есть хочется понять на примере "проблема-решение" что все эти закорючки значат.
Там все просто.
В С++03 при присваивании или инициализации из временного объекта происходит сначала копирование всего содержимого объекта в новый, а потом разрушение временного. std::vector, например — нужно выделить память, скопировать все объекты, которые можуг быть тяжелыми сами по себе, хотя достаточно было всего лишь перекинуть указатель на буфер и обойтись вообще без выделений и копирований.
В С++11 ссылки на rvalue позволяют явно прописать, как именно перемещать содержимое из временного объекта, и компилятор будет этим способом по возможности пользоваться.
Здравствуйте, Banned by IT, Вы писали:
BBI>1М элементов BBI>sort для vector<string> — 1.852954 sec, дофигища копирований BBI>sort для vector<string>, string c поддержкой move constructor/operator — 0.532721 sec, ни одного копирования BBI>Разница в 3.478280 раза
Я может че не понимаю... Если нужна производительность сортировки массива, то
1) можно хранить указатели на объекты (в данном случае строк).
2) делать эффективный swap элементов массива, который можно реализовать и в рамках C++03.
Re[8]: Кто что из c++0x использует. И кто на что нарвался?
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, jazzer, Вы писали:
J>>Ну да, либо ты делаешь все на вызывающей стороне, либо на вызваемой U>казалось бы палка о двух концах, но я так не считаю U>напомню о чем я говорю, чтобы мы говорили об одном и том же: U>SetB(B&&) с точки зрения дизайна вносит необоснованное ограничение (невозможность подставить lvalue) ради некоторой оптимизации U>SetB(B b) не имеет такого ограничения и тоже позволяет применить оптимизацию
Это ложный выбор. Правильно объявлять оба варианта: SetB(B&&) для случаев, когда аргумент — временный объект, и SetB(const B&) — для случаев, когда объект нормальный долгоживущий.
Здравствуйте, Banned by IT, Вы писали:
BBI>variadic templates
а можно примеров их удобного использования? пока встречал только всякую плохочитабельную содомию..
хотя у меня был ровно один случай, где они бы пригодились..