В процессе поиска идей для constexpr вектороподобного контейнера я наткнулся на контейнер small_vector Фолли. Я читал реализацию и был озадачен этой частью moveObjectsRightAndCreate:

 for (; in != first && out > lastConstructed;) {
      // Out должен быть уменьшен до того, как будет выброшено исключение, чтобы
      // защита от отката знала, с чего начать.
      --out;
      new (out) T(std::move(*(-in))));
    }
    for (; in != first;) {
      --out;
      *out = std::move(*(-in));
    }
    for (; out > lastConstructed;) {
      --out;
      new (out) T(create());
    }
    for (; out != first;) {
      --out;
      *out = create();
    }

Мое понимание таково: Для частей массива, где память была неинициализирована, они используют размещение new с std::move. Для частей массива, из которых объекты были ранее перемещены, используется присвоение move.

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

ParadoxFox

Ответов: 1

Ответы (1)

Почему бы не использовать новое размещение для обоих случаев

Возможно, потому что это не позволит им указать, что деструкторы элементов не будут вызываться при вставке (в случае, когда емкость не растет). Похоже, что они не указывают свой API так точно, но они могут считать, что это неявно ожидается.

Или они могут предполагать или ожидать, что присвоение теоретически может быть более эффективным для какого-то типа, чем разрушение + строительство.

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

Почему бы не использовать присвоение перемещения для обоих случаев?

Потому что поведение присваивания move нетривиального типа в неинициализированной памяти не определено.

2022 WebDevInsider