C++ Set emplace против вставки, когда объект уже создан

class TestClass {
    public:
     TestClass(string s) {

     }
   };

Когда есть TestClass, я понимаю разницу между emplace и insert (конструкции emplace на месте при вставке копий)

   set<TestClass> test_set;
   test_set.insert(TestClass("d"));
   test_set.emplace("d");

Однако, если объект TestClass уже существует, чем они отличаются с точки зрения механизма и предварительной производительности?

   set<TestClass> test_set;
   TestClass tc("e");
   test_set.insert(tc);
   test_set.emplace(tc);

2 ответа

Решение

emplace выполняет свою работу путем идеальной пересылки своих параметров в правильный конструктор (используя, вероятно, новое размещение в большинстве реализаций).
Из-за этого в вашем случае он перенаправляет ссылку на lvalue и, таким образом, скорее всего, вызывает конструктор копирования.
Какая сейчас разница с push_back что явно вызывает конструктор копирования?

Мейерс также ссылается на это в одной из своих книг, и он говорит, что нет никакой реальной выгоды в вызове emplace если у вас уже есть экземпляр объекта.

Тщательное использование emplace позволяет создавать новый элемент, избегая ненужных операций копирования или перемещения. Конструктор нового элемента вызывается с точно такими же аргументами, что и для emplace, пересылаемыми через std::forward(args)....

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

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