Приведение к rvalue ссылки на "форсирование" перемещения возвращаемого значения - уточнение
Хорошо, я начинаю получать список ссылок на rvalue (я думаю). У меня есть этот фрагмент кода, который я писал:
#include <iostream>
using namespace std;
std::string get_string()
{
std::string str{"here is your string\n"};
return std::move(str); // <----- cast here?
}
int main ()
{
std::string my_string = std::move(get_string()); // <----- or cast here?
std::cout << my_string;
return 0;
}
Итак, у меня есть простой пример, где у меня есть функция, которая возвращает копию строки. Я прочитал, что это плохо (и получил дампы ядра, чтобы доказать это!), Чтобы вернуть любую ссылку на локальную временную переменную, поэтому я не стал пытаться это делать.
В назначении в main()
Я не хочу копировать-создавать эту строку, я хочу переместить-построить / назначить строку, чтобы избежать слишком частого копирования строки.
Q1: я возвращаю "копию" временной переменной в
get_string()
- но я привел возвращаемое значение к rvalue-red. Это бессмысленно или делает что-нибудь полезное?Q2: Предполагая, что ответ Q1 - мне не нужно этого делать. Затем я перемещаю свежую копию временной переменной в
my_string
, или я двигаюсь непосредственно переменную tempstr
вmy_string
,Q3: какое минимальное количество копий вам нужно, чтобы получить строковое возвращаемое значение, сохраненное во "внешней" (в моем случае в main()) переменной, и как вы это делаете (если я еще не достиг Это)?
2 ответа
Я возвращаю "копию" временного var в get_string() - но я привел возвращаемое значение к rvalue-red. Это бессмысленно или делает что-нибудь полезное?
Вам не нужно использовать std::move
в этой ситуации, поскольку локальные переменные, возвращаемые по значению, "неявно перемещаются" для вас. Для этого в Стандарте есть специальное правило. В этом случае ваш ход пессимистичен, поскольку может предотвратить RVO (об этом предупреждает clang).
Q2: Предполагая, что ответ Q1 - мне не нужно этого делать. Затем я перемещаю свежую копию переменной temp в my_string или перемещаю непосредственно переменную temp str в my_string.
Вам не нужно std::move
результат звонка get_string()
, get_string()
это значение, которое означает, что конструктор перемещения my_string
будет вызываться автоматически (до C++17). В C++ 17 и выше обязательное удаление копии гарантирует, что никакие перемещения / копии не произойдут (с prvalues).
Q3: какое минимальное количество копий вам нужно, чтобы получить строковое возвращаемое значение, сохраненное во "внешней" (в моем случае в main()) переменной, и как вы это делаете (если я еще не достиг Это)?
Зависит от Стандарта и от того, имеет ли место RVO. Если произойдет RVO, у вас будет 0 копий и 0 ходов. Если вы нацелены на C++ 17 и инициализируете из prvalue, у вас гарантированно будет 0 копий и 0 ходов. Если ни то, ни другое не произойдет, у вас, вероятно, будет один ход - я не понимаю, почему здесь должна происходить какая-либо копия.
Вам не нужно использовать std::move
на возвращаемое значение, которое является локальной переменной. Компилятор сделает это за вас:
Если выражение является выражением lvalue, которое является (возможно, заключенным в скобки) именем объекта длительности автоматического хранения, объявленного в теле или в качестве параметра самой внутренней включающей функции или лямбда-выражения, тогда разрешите перегрузку, чтобы выбрать конструктор, который будет использоваться для инициализации объекта. возвращаемое значение выполняется дважды: сначала, как если бы выражение было выражением rvalue (таким образом, оно может выбрать конструктор перемещения), и если подходящее преобразование не доступно или если тип первого параметра выбранного конструктора не является ссылкой на rvalue тип объекта (возможно, cv-квалифицированный), разрешение перегрузки выполняется во второй раз, с выражением, рассматриваемым как lvalue (поэтому он может выбрать конструктор копирования, ссылаясь на неконстантный).