я следующий классRValue ссылки без станд :: двигаться
class widget {
// The methods only print their name, i.e. c'tor, destructor etc.
public:
widget();
widget(const widget&);
widget(widget&&);
~widget();
auto operator=(const widget&) -> widget&;
auto operator=(widget&&) -> widget&;
};
, который я использую в следующем коде
#include "widget.h"
auto main() -> int {
widget c(std::move(widget()));
c = std::move(widget());
return 0;
};
Полученное поведение является приемлемым для меня. В первом вызове создается виджет, затем вызывается конструктор перемещения, а деструктор вызывается во временном виджете.
Второй вызов делает то же самое, ожидание вызова оператора присваивания перемещения вместо конструктора перемещения. Оставляя основной метод, деструктор вызывается на c
.
Сейчас идет интересная часть:
#include "widget.h"
auto main() -> int {
widget c((widget()));
c = widget();
return 0;
};
Если я выхожу из вызов std::move
, первый случай перестает работать и приводит только один конструктор вызова. В то время как второй случай все еще работает по-прежнему.
Что мне здесь не хватает? Почему эти два вызова функций обрабатывают их параметры по-разному? Я пробовал это на gcc и clang.
'(widghet())' является prvalue, то есть значением r, поэтому он перемещается (если возможно). 'std :: move' не перемещается, он просто меняет категорию значений выражения. Если бы это выражение имело соответствующую категорию значений, это излишне. – Columbo
Скобки необходимы, иначе выражение вычисляется как указатель на функцию, которая не принимает параметров и возвращает «виджет». – mike
Может быть, ваш компилятор оптимизирует некоторые конструкции и копии для вас? –