Причины использования надлежащего конструктор перемещения много:
конвенции. Рассмотрим следующий код:
Foo foo;
Foo bar(std::move(foo));
Если вы видите, что код, это обильно ясно, что вы пытаетесь сделать: вы двигаетесь foo
в bar
. В отличие от этого:
Foo foo;
Foo bar(&foo);
Что это значит? Сохраняет ли указатель на другом Foo
? Есть Foo
какой-то тип связанного списка узлов? Вы должны найти его в документации для конструктора указателей Foo
.
Вы не можете получить указатель на prvalues. Foo bar(Foo{})
будет (pre-C++ 17) создать временное значение prvalue, а затем перейти от него к bar
(перемещение может быть отменено до C++ 17). Но вы не можете этого сделать: Foo bar(&Foo{})
.
Вы получаете автоматическое движение от вещей, где это имеет смысл. C++ 17, обобщенная элизии делает многие из этих автоматических движений уходят, но есть некоторые, которые остаются:
Foo function()
{
Foo foo;
//Do stuff
return foo;
}
Это будет двигаться от foo
без вызова std::move
. Причина в том, что foo
- локальная переменная, которая вот-вот будет уничтожена. Возвращение его таким образом означает, что вполне разумно перейти от него к возвращаемому значению.
Ваш путь потребовал бы явного написания return &foo
. И это делает вещи довольно сложными с выводом типа auto
. Такая функция выводит Foo*
, что означает, что вы только что вернули висячий указатель. Если вы делаете return foo;
, он выводит Foo
prvalue с автоматическим перемещением (которое может быть отменено).
Нет необходимости в nullptr
проверках. Если вы возьмете Foo*
, возможно, кто-то передаст нулевой указатель. В то время как со ссылкой это гораздо более маловероятно (и они уже вызывают UB).
Если мы хотим двигаться поддержку с существующими конструкциями языка, мы бы просто использовали не- const
ссылка означает «движение», а не указатель. Давая ему свой синтаксис, дайте понять, когда мы что-то двигаем, а когда нет.
Ну, для начала вы не можете взять адрес rvalue ... – Brian
Преимущества заключается в том, что конструктор перемещения будет автоматически использоваться в соответствующих контекстах перемещения/копирования. Конструктора «указателя» не будет. – AnT
Кроме того, ссылка не может быть нулевой, но может быть указатель, поэтому вам нужно будет явно проверить это условие перед заменой. –