Comments 17
std::vector<std::string> strings;
void addString(std::string &&string) {
strings.emplace_back(std::move(string));
}
addString(std::string("hello world!"));
Чуть подробнее в документации к std::vector::emplace_back.
Слегка разница будет: аргумент push_back всегда T, то есть будет создана копия при вызове метода, а вот само это значение будет move-нуто в вектор. Если же созжания объекта до его непосредственного положения в векторе надо избежать, достаём emplace с параметрами конструктора (в том числе move-конструктора).
Прошу прощения, ошибся: мне казалось, что такой перегрузки не сделали, а она есть: которая с C++11.
Вот ещё статья более понятная про это всё habr.com/ru/post/322132
разработчику библиотек желательно понимать, т.к. нужно обеспечить movable поведение.
в разных непонятных ситуациях, когда код на вид вполне нормален, а компилятор ругается. понимание, что нельзя присваивать rvalue и главное сообразить, что это rvalue — сократит время исправления ошибки.
в общем нужно, но тяжеловато. пока читаешь — более менее понятно. навскидку в обычной жизни — лезешь проверять в справочник.
интересно, а компилятор может выдать информацию, какие выражения к какому типу относятся ??
Компилятор занят синтактическим , а не семантическим анализом ) Обычно его ругань более явная "нельзя привязать А к Б"
Через https://cppinsights.io/ кое что можно прояснить,
Но хотелось бы не гадать на стандарте, а точно знать что компилятор думает о той или иной конструкции
Битовые поля – удобный инструмент для низкоуровнего программирования, однако, их реализация несколько выпадает из общей структуры категорий выражений.
В то же время, взять адрес битового поля или инициализировать им неконстантную ссылку не получится.
Второе утверждение верно, а первое не совсем. Когда речь идет об identity,имеется в виду любой вид уникальности. В Си++ ставится различие между storage (область памяти) и memory location (ячейка памяти).Ряд объектов обладает и тем и другим, например, объекты скалярного типа или члены классов и элементы массивов этого типа. У класса есть область памяти, но нет ячейки, в то время как члены могут занимать ячейки. У ссылок в составе классов и у битовых полей (которые по определению являются членами класса) есть ячейка памяти, но нет области памяти. Уникальной особенностью битовых полей является то, что несколько полей ненулевого размера могут занимать одну ячейку
Скорее в уникальную ситуацию можно было бы записать члены объединения, т.к. тут перекрываются области памяти. Однако нам категорически запрещено рассматривать объединение как два или более объектов существующих одновременно. И это как раз из-за того, что система категорий фундаментальна.
Указатель и ссылка обращаются к области памяти. Поэтому для битовых полей их и не может быть. Поэтому невозможна ссылка на ссылку. Однако ВСЯ ячейка памяти целиком является субъектом выражения, поэтому, если а
и b
- битовые поля с общей ячейкой, то результат выражения a++ + ++b
является таким же неопределенным поведением как и a++ + ++a
, где одно и то же значение (одна и та же ячейка) меняется дважды.
Не кажется ли мне, что это и есть причина существования системы категорий? В противном случае вся эти правила покажется нелогичным собранием ограничений, и непонятно накой и, главное, зачем они были так написаны?
Категории выражений в C++