为什么地图放置两次调用右值构造函数

时间:2018-07-15 13:05:00

标签: c++11

class twoMem {
    int _a;
    int _b;

    public:
    twoMem() { 
        std::cout << "default constructor" << std::endl; 
    }

    twoMem(int a, int b) :_a(a), _b(b) { 
        std::cout << "constructor called" <<   std::endl; 
    }

    twoMem(const twoMem& other) {
        std::cout << "copy constructor called" << std::endl;
        _a = other._a;
        _b = other._b;
    }

    twoMem(const twoMem&& other) {
        std::cout << "rvalue copy constructor called" << std::endl;
        _a = other._a;
        _b = other._b;
    }

    ~twoMem() {
        std::cout << "destructor called" << std::endl; 
    }
};

int main()
{
    std::map<std::string, twoMem> myMap{};
    myMap.emplace(std::make_pair("foo", twoMem{ 1, 2 }));
    return 0;
}

输出:

constructor called
rvalue copy constructor called
rvalue copy constructor called
destructor called
destructor called
destructor called

1 个答案:

答案 0 :(得分:0)

首先,make_pairtwoMem参数移到它返回的pair<const char*, twoMem>中。其次,emplace()从那个位置移到实际节点。

制作

myMap.emplace("foo", twoMem{ 1, 2 });

然后the move constructor is only called once。这就是map::emplace的重点。

您可以将副本复制为零或移动构造函数this way

myMap.emplace(std::piecewise_construct, std::make_tuple("foo"), std::make_tuple(1, 2));

尽管可以说这种治愈方法可能比疾病更糟,因为现在您正在构建和复制元组,这至少和复制twoMem一样昂贵。