Вопросы о семантике postblit и move

Я уже задал аналогичный вопрос некоторое время назад, но я до сих пор неясно о некоторых деталях.

  • При каких обстоятельствах конструктор postblit называется?

  • Какова семантика перемещения объекта? Будут ли они удалены и/или уничтожены?

  • Что произойдет, если я верну локальную переменную по значению? Будет ли оно неявно перемещено?

  • Как сделать выражение для rvalue? Например, как будет выглядеть общий подкачка?

Ответы

Ответ 1

  • Конструктор postblit вызывается всякий раз, когда структура копируется - например. при передаче структуры в функцию.

  • Перемещение - побитовая копия. Конструктор postblit никогда не вызывается. Деструктор никогда не называется. Биты просто копируются. Оригинал был "перемещен", и поэтому ничего не нужно создавать или уничтожать.

  • Он будет перемещен. Это яркий пример движения.

  • Существует множество различных ситуаций, о которых вам нужно будет беспокоиться о функции swap, если вы хотите сделать ее максимально эффективной. Я бы посоветовал просто использовать функцию swap в std.algorithm. Классический обмен приведет к копированию и, таким образом, вызовет конструктор postblit и деструктор. Переходы обычно выполняются компилятором, а не программистом. Однако смотря на официальную реализацию swap, похоже, что он играет некоторые трюки, чтобы получить семантику перемещения из сделки, где она может. Несмотря на это, ходы, как правило, выполняются компилятором. Они оптимизируют его, когда он знает, что он может (RVO быть классическим случаем, когда он может).

В соответствии с TDPL (стр. 251) есть только 2 случая, когда D гарантирует, что движение будет иметь место:

  • Все анонимные значения перемещаются, а не копируются. Вызов this(this) никогда не вставлен, когда источник является анонимным значением r (например, a временный, как показано в функции hun выше).
  • Все названные временные ряды, которые распределены по стекам внутри функции и затем вернул вызов this(this).
  • Нет никакой гарантии, что наблюдаются другие потенциальные нарушения.

Итак, компилятор может использовать перемещения в другом месте, но нет гарантии, что он будет.

Ответ 2

Насколько я понимаю:

1) Когда копируется структура, в отличие от перемещенного или построенного.

2) Семантика точки перемещения состоит в том, что ни одна из двух не должна произойти. Новое расположение структуры инициализируется битовой копией структуры, а старое местоположение выходит за пределы области видимости и становится недоступным. Таким образом, структура "перемещается" от А к В.

3) Это типичная ситуация перемещения:

S init(bool someFlag)
{
    S s;
    s.foo = someFlag? bar : baz;
    return s; // `s` can now be safely moved from here...
}

// call-site:
S s = init(flag);
//^ ... to here.