EP>>Теперь при возврате по значению И сохранению по значению компилируется, а раньше нет — ибо теперь возможно гарантированное RVO. MA>И за счет чего это достигается?
Не "за счёт чего", а "благодаря чему". "За счёт" это когда в одном месте улучшили ценой ухудшения в другом.
Если коротко, то в стандарте просто перестали требовать наличия move-конструктора там, где раньше он формально требовался, при том, что большинство реализаций его не использовало, конструируя сразу нужный объект, без создания временных.
Если длинно, то: поменяли определения value-категорий и правила инициализации. Раньше prvalue могло обозначать временный объект,
Скрытый текст
и было непонятно, почему prvalue тогда не подкласс glvalue, которое по определению denotes an object
а теперь это выражение, которое используется для инициализации объекта, причём объект подаётся "снаружи" (The result of a prvalue is the value that the expression stores into its context.). MA>Работает ли это при кросс-модульной не PGO компиляции?
Как это может помешать?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Начиная с C++11 есть list-initialization:
А как это относится к обсуждаемой теме?
Это просто ещё один способ сконструировать объект где-то в памяти.
А RVO со товарищи, как и возможность ими управлять, -- это про то, ГДЕ конструировать объект и про передачу владения им между фреймами разных контекстов, а не про как конструировать...
p. s.
Гарантированое RVO -- это шаг в направлении, которое мне нравится
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>>>И в этом случае, кстати, можно было бы не требовать наличие открытого конструктора копии EP>>Начиная с C++11 есть list-initialization: E>А как это относится к обсуждаемой теме? E>Это просто ещё один способ сконструировать объект где-то в памяти.
Так ты внимательней смотри — тип NonCopyableNonMovable, при этом мы возвращаем его из функции (наличие конструктора копирования/перемещения не требуется). До появления return {...}; в C++11 так было сделать нельзя. И для других способов сконструировать объект в C++11 это не работает, только для формы return {...};.
Здравствуйте, rg45, Вы писали:
R>Всем привет!
R>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено? Разумеется, состояние объекта должно позволять разрушить этот объект, это сомнению не прдвергается. Но достаточно ли этого? Ведь помимо физического тела у объекта есть еще и логическое состояние — его душа, так сказать. Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения?
Всем добра. Поделюсь своим мнением.
Если хочется, чтобы всегда оставалась "душа", то в вашем случае вместо move надо делать swap. Например, с объектом, сконструированным по умолчанию.
Здравствуйте, SaZ, Вы писали:
SaZ>Всем добра. Поделюсь своим мнением. SaZ>Если хочется, чтобы всегда оставалась "душа", то в вашем случае вместо move надо делать swap. Например, с объектом, сконструированным по умолчанию.
В данном случае акцент чуть другой. В том-то и дело, что мне НЕ хочется. И интересует меня, чем меня за это будут бить
Подход со swap хорош, когда речь идет о перемещающем операторе присваивания. Для конструктора же это означает, что мы сперва должны сконструировать все поля значениями по умолчанию, и только потом уже позвать swap в теле конструктора. Вот это конструирование полей значениями по умолчанию, в то время, когда у нас есть возможность сразу проинициализировать их нужными значениями, мне очень не нравится.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Так ты внимательней смотри — тип NonCopyableNonMovable, при этом мы возвращаем его из функции (наличие конструктора копирования/перемещения не требуется). До появления return {...}; в C++11 так было сделать нельзя. И для других способов сконструировать объект в C++11 это не работает, только для формы return {...};.
Ну это прикольно, но далеко не RVO. Попробуй, например, вернуть таким образом объект рекурсивно (
NonCopyableNonMovable g(); // не важно как она там внутри устроена, но
NonCopyableNonMovable f()
{
return g(); // что тут пишем?
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали:
R>Подход со swap хорош, когда речь идет о перемещающем операторе присваивания. Для конструктора же это означает, что мы сперва должны сконструировать все поля значениями по умолчанию, и только потом уже позвать swap в теле конструктора. Вот это конструирование полей значениями по умолчанию, в то время, когда у нас есть возможность сразу проинициализировать их нужными значениями, мне очень не нравится.
Может я что-то не так понял, но вам в любом случае нужно как-то сконструировать объект c валидным состоянием (в смысле заполнить перемещаемый объект валидным состоянием), если вы ходите использовать его после std::move. Но мне кажется, что стоит относится к перемещённым объектам как к непригодным для последующего использования.
Во всяком случае ReSharper мне кидает предупреждения, если я использую перемещённый объект.
Здравствуйте, rg45, Вы писали:
A>>Ну не может в процессе перемещения из одной вещи получаться две .
R>Вот! Очень хорошо сказал. Концепция плывет.
Так это врождённый дефект move-семантики же?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, TimurSPB, Вы писали:
R>>Вопрос несколько философский. Правомерно ли делать какие-либо допущения о состоянии объета, в самом общем случае, после того, как его содержимое было перемещено? Разумеется, состояние объекта должно позволять разрушить этот объект, это сомнению не прдвергается. Но достаточно ли этого? Ведь помимо физического тела у объекта есть еще и логическое состояние — его душа, так сказать. Так вот как быть с ней — нужно ли заботиться о том, чтобы после перемещения объект оставался в целостном состоянии с точки зрения логики программы — на тот случай, если кому-то захочется продолжать пользоваться объектом после его перемещения? TSP>В писании сказано: TSP>
TSP>Objects of types defined in the C++ standard library may be moved from (12.8). Move operations may be explicitly specified or implicitly generated. Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state.
TSP>Как я понимаю, в общем случае нужно заботиться о целостности объекта после его перемещения.
да уж