Просто я действительно не знаю где применять предложенную Вами запись. Обычно rvalue применяется в качестве параметров, а не как объект создаваемый непосредственно в коде.
Вы не понимаете. Нет никакого rvalue содержимого. Rvalue&rvalue есть лишь свойство выражения. Чтобы вызвать move семантику, нужно использовать rvalue выражение, для этого применяется, в частности, std::move(или как вы делали static_cast). Посмотрите мою статью. Может прояснит немного.
Проблема тут в том, что даже если все члены класса поддерживают move-семантику, такие методы не генерируются компилятором автоматически
Не правда. Они генерируется, за исключением:
Класс A не содержит явного объявления конструктора копирования
Класс A не содержит явного объявления оператора копирования
Класс A не содержит явного объявления оператора перемещения
Класс A не содержит явного объявления деструктора
Конструктора копирования не был явно помечен как deleted
Widget _var1 = someWidget1+someWidget2; //Будет вызван move-конструктор(если он есть)
Widget&& var1 = someWidget1+someWidget2; //На стеке будет создан объект, посредством move ctor(если он есть), после чего на этот объект будет создана ссылка.
Если move ctor отсутствует, значит будет вызван copy ctor.
Widget&& var1 = static_cast<Widget&&>(someWidget);//создаём объект на стеке, воруя содержимое someWidget. someWidget нельзя использовать более
Widget var2,var3;//default ctor
var2=var1;//operator=(const Widget& rhs)
var3=var1;//operator=(const Widget& rhs)
Т.е. в последних двух строчках происходит обычное копирование. А вот есл написать так:
Если Вы возвращаете(T&& foo()) ссылку, тогда она указывает на объект, который находится внутри стека функции, а следовательно она «висит». Т.е. разницы с lvalue ref нет. Где хранится объект? Насколько я понимаю, если создается rvalue ref(int&& var1 = 5;) то будет создан объект на стеке, на который будет указывать ссылка. Т.е. опять никаких отличий. А вот теперь семантика: Ваш пример(Widget&& var1 = someWidget;) не скомпилируется, т.к. нельзя привязать rvalue ref к lvalue, но если немного модифицировать: Widget&& var1 = Widget(someWidget); или Widget&& var1 = std::move(someWidget); то всё будет хорошо(смотри предыдущее предложение)
Я постоянно пишу на C++ и могу сказать, что язык становится проще. Да появляются новые вещи, которые лучше бы знать. Но очень многое из этого не будет применяться большим числом С++ программистов-прикладников, т.к… многое из нововведений необходимо для написания кода библиотек.
Возвращается «висячая ссылка». Как и с lvalue ref это «запрещенный» приём. Можете думать об rvalue ref так же как и lvalue ref, в плане хранения. Вся разница между ними в семантике применения.
На самом деле всё довольно просто; просто данная статья Скота не очень удачная, он чересчур сложно объяснил вещи, которые можно было прям выдрать из стандарта и всё бы встало на свои места.
Не нравится слово обратитесь к Гербу. Я передал то, что слышал в его выступлениях. Сам я не сталкивался с такой необходимостью. А ссылка, которую я привёл есть лишь результат ~10 секундного «гугления». Я не знаю о каких конкретно алгоритмах говорил Герб.
Спросите Герба, или еще кого из группы по сборщику. Продвижение коллектора связано именно с этим, а не как замена только что появившимся умным указателям.
memory_order_acquire, как и memory_order_release по одиночке ничего не гарантируют, только в паре. Хотя тут, по всей видимости, Вы правы; в данном конкретном случае нужна только синхронизация между последним store и read частью exchange.
Не правда. Они генерируется, за исключением:
Класс A не содержит явного объявления конструктора копирования
Класс A не содержит явного объявления оператора копирования
Класс A не содержит явного объявления оператора перемещения
Класс A не содержит явного объявления деструктора
Конструктора копирования не был явно помечен как deleted
Если move ctor отсутствует, значит будет вызван copy ctor.
Т.е. в последних двух строчках происходит обычное копирование. А вот есл написать так:
Да, любое выражение, которое имеет имя есть lvalue.
Именно.
У меня нет.