Я экспериментировал с использованием emplace () вместо std :: map вместо insert. У меня есть простая тестовая программа ниже:
#include <iostream>
#include <map>
#include <string>
class CTest
{
public:
CTest() : Value(0), Name() { std::cout << "Default constructor" << std::endl; };
CTest(int val, const std::string &name) : Value(val), Name(name) {
std::cout << "Parameterized constructor" << std::endl; }
CTest(const CTest& test) {
Value = test.Value; Name = test.Name; std::cout << "Copy Constructor" << std::endl; }
CTest(CTest&& test) noexcept {
Value = test.Value; Name = test.Name; std::cout << "Move Constructor" << std::endl; }
CTest& operator=(const CTest& test) {
Value = test.Value; Name = test.Name; std::cout << "Copy assignment" << std::endl; return *this; }
CTest& operator=(CTest &&test) noexcept {
Value = test.Value; Name = test.Name; std::cout << "Move assignment" << std::endl; return *this; }
~CTest() { std::cout << "Destructor" << std::endl; }
private:
int Value;
std::string Name;
};
int main()
{
CTest t1(1, "hello");
CTest t2(2, "hello");
std::map<int, CTest> testMap;
testMap[1] = t1; //1
testMap.emplace(2, t2); //2
testMap.emplace(3, CTest(3, "hello")); //3
testMap.emplace(std::piecewise_construct, std::forward_as_tuple(4), std::forward_as_tuple(4, "hello")); //4
testMap.emplace(std::piecewise_construct, std::forward_as_tuple(4), std::forward_as_tuple(std::move(t1))); //5
return 0;
}
Выход для каждого из них:1Конструктор по умолчаниюКопировать назначение
2Копировать конструктор
3Параметризованный конструктор
Перемещение конструктора
Деструктор
4Параметризованный конструктор
5Перемещение конструктора
Деструктор
1 включает в себя наибольшее количество копий: создайте запись на карте с конструктором по умолчанию, а затем присвойте копию. Я был удивлен, увидев вызов деструктора для 3 и 5. В обоих случаях переданное значение является rvalue. Так создается ли временное значение из переданного значения r, которое удаляется после использования? Возникает вопрос: как правильно использовать emplace? Должны ли вы просто передать аргументы конструктора, как в 4? Это лучший результат, как показывают мои результаты.