使用复制构造函数放置和 try_emplace

emplace and try_emplace with copy constructor

我对 emplace 和 try_emplace 有疑问,因为它们在移动对象时总是使用复制构造函数。

#include <iostream>
#include <unordered_map>
#include <map>

using namespace std;

class Too {
public:
     Too(int x, int y):x_(x), y_(y) {
        cout << "init " << x_  << endl;
    }
    Too(const Too& too):x_(too.x_+1), y_(too.y_+1) {
        cout << "Copy happen: x = " << x_ << endl;
     }
    ~Too() {
        cout << "delete too " << x_ << endl;
    }
private:
    int x_, y_;
};



std::map<int, Too> v;


int main()
{
    v.emplace(100, Too{ 100,23 });

    v.try_emplace(12, 12, 13);

    Too t = Too(10, 11);
    v.try_emplace(11, std::move(t));
}


输出 初始化 100 复制发生:x = 101 也删除 100 初始化 12 初始化 10 复制发生:x = 11 也删除 10 也删除 101 也删除 12 也删除 11


可以看到,只有v.try_emplace(12, 12, 13)没有使用拷贝构造函数。 v.emplace(100, Too{ 100,23 }) 和 v.try_emplace(11, std::move(t)) 都调用复制构造函数。

那我用std::move(t)怎么会呢?

如有任何建议,我们将不胜感激。

谢谢,

由于您为 class 提供了复制构造函数,移动构造函数 Too::Too(Too&&) 不会由编译器隐式生成

此外,当class没有可用的移动构造函数时,可以使用复制构造函数。


要使用移动构造函数,您必须显式提供适当的 user-defined 移动构造函数 Too::Too(Too&&),然后您将获得所需的结果。

您可以通过添加 Too(Too&&) = default; 或编写您自己的移动构造函数来添加移动构造函数,它将在构造函数初始化列表中进行初始化。