Подтвердить что ты не робот

Emplace_back() не ведет себя так, как ожидалось

Я написал простую программу для создания объектов внутри стандартных контейнеров библиотеки. Вот что я написал:

#include <vector>
#include <iostream>

class AB
{
public:
   explicit AB(int n);
   AB(const AB& other) = delete;
   AB(AB&& other);
   AB& operator=(const AB& other) = delete;
   AB& operator=(AB&& other) = default;
private:
   int i;
};

AB::AB(int n): i( n )
{
   std::cout << "Object created." << std::endl;
};

AB::AB(AB&& other): i( std::move(other.i) )
{
   std::cout << "Object moved." << std::endl;
};

int main()
{
   std::vector< AB > v;
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);
};

Я скомпилировал его с g++ (версия 4.8.2). После выполнения вывода я получил:

Object created.
Object created.
Object moved.
Object created.
Object moved.
Object moved.

Но я ожидал чего-то вроде этого:

Object created.
Object created.
Object created.

Я думал, что все дело в том, чтобы избавиться от вызовов конструктора движения. Существуют ли какие-либо требования в классе AB, которые не выполняются?

Спасибо за вашу помощь.

4b9b3361

Ответ 1

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

   std::vector< AB > v;
   v.reserve(3);
   v.emplace_back(1);
   v.emplace_back(2);
   v.emplace_back(3);

дает

Object created.
Object created.
Object created.

В gcc 4.8.2. Обратите внимание, что вы можете отслеживать рост вектора в исходном коде, глядя на v.capacity().

Ответ 2

Точка размещения - это избавиться от вызовов конструктора COPY. Вероятно, он перемещает объекты из-за изменения размера вектора, когда он заполнен. Перемещение объекта в порядке. Копирование объекта дорого.