Нужен ли конструктор / назначение перемещения для RVO в C ++ 11? - PullRequest
0 голосов
/ 26 июня 2019

Например:

В принятом ответе https://stackoverflow.com/a/14623480/1423254,

Будет ли копирование elision и RVO работать для классов без конструкторов перемещения?

Да, RVO все еще активен. На самом деле, ожидается, что компилятор выберет: RVO (если возможно)

В принятом ответе https://stackoverflow.com/a/38043447/1423254,

Под не- гарантированно скопируйте правила исключения, это создаст временное значение, а затем переместится из этого временного значения в возвращаемое значение функции.Эта операция перемещения может быть исключена, но у T по-прежнему должен быть доступный конструктор перемещения, даже если он никогда не используется.

Дело в том, что я думал, что RVO и "lvalue перемещаются" (или как вызватьони) - это две совершенно разные операции, но мой коллега сказал мне, что для того, чтобы RVO начал работу, возвращаемому классу нужен конструктор перемещения.Поэтому я проверил интернет и ТАК, и, очевидно, информация не может быть найдена быстро ...

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Нет, если конструктор копирования доступен.

До C ++ 17 и гарантированного разрешения копирования, либо конструктор перемещения ИЛИ конструктор копированиядолжен был быть доступен для кода, чтобы быть законным.Elision была просто оптимизацией и не влияла на то, будет ли код компилироваться или нет.

То есть, существует двухэтапный процесс:

  • Оценить, является лиутверждение return <expr>; является допустимым, которое до C ++ 17 требует (за исключением преобразований), что должен присутствовать либо конструктор копирования, либо, при наличии временного, конструктор перемещения и доступный .
  • Если возможно, примените Оптимизацию возвращаемого значения и исключите вызов для указанного конструктора.

Учитывая это, давайте рассмотрим кавычки:

Копирует elision и RVO все еще будет работать для классов без конструкторов перемещения?

Да, RVO все еще включается. Фактически, компилятор должен выбрать: RVO (если возможно)

Да следует понимать в контексте законного кода .Если код не компилируется, то вопрос спорный.

В соответствии с правилами негарантированного копирования, это создаст временное значение, а затем переместится из этого временного значения в возвращаемое значение функции.Эта операция перемещения может быть исключена, но у T по-прежнему должен быть доступный конструктор перемещения, даже если он никогда не используется.

Это кратчайший путь;Попытка сформулировать предложение с учетом возможного отсутствия конструктора перемещения и, следовательно, отступления к конструктору копирования, просто испортила бы объяснение, и ФП не дал никаких указаний на то, что рассматривалась такая ситуация.

1 голос
/ 26 июня 2019

Краткий ответ: нет.

RVO также существовал до C ++ 11, когда не было такого понятия, как «конструктор перемещения».В этом случае единственным требованием был конструктор копирования.

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * .где "обязательное удаление копии" еще не было частью языка.

Начиная с C ++ 17, компилируется следующий код (с гарантией нулевого копирования / перемещения):

struct foo
{
    foo() = default;
    foo(const foo&) = delete;
    foo(foo&&) = delete;
};

foo get_foo() { return foo{}; }

int main()
{
    foo f{get_foo()};
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...