Приведение к 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, или я двигаюсь непосредственно переменную temp str в 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 (поэтому он может выбрать конструктор копирования, ссылаясь на неконстантный).

Другие вопросы по тегам