为什么insert在std::unordered_set中调用复制构造函数



我有一个std::unordereded_set指针。如果我做

int main()
{
std::unordered_set<std::unique_ptr<int>> set;
set.insert(std::make_unique(3));
}

一切正常,insert调用move构造函数(我认为(。然而,我有一个不同的情况,类似于以下代码

std::unordered_set<std::unique_ptr<int>> set;
void add(const std::unique_ptr<int>& obj) {set.insert(obj);}
int main
{
std::unique_ptr<int> val = std::make_unique<int>(3);
add(std::move(val));
}

并且这不会编译。它提供

状态错误C2280’std::unique_ptr<int,std::default_delete>:unique_ptr(const std::unique_ptr<int,std::default_delete>&(':试图引用已删除的函数

这意味着它正在尝试调用复制构造函数(对吗?(。所以问题是:为什么insert在函数内部时不移动对象?我还尝试将指针传递到unique_ptr,甚至在几乎所有地方添加std::move,但复制构造函数总是被称为

void add(const std::unique_ptr<int>& obj) 

它可以归结为一些基本的东西:根据定义,你不能移动一个恒定的物体"移动";基本上意味着从移动的物体中取出内脏,并将所有内脏推入新的、移动到的物体中(以最有效的方式,以外科医生的精度(。如果移动的from对象是const,则不能执行此操作。这是不可触碰的。它必须保持原状。

如果参数是一个右值引用,您应该能够做到这一点:

void add(std::unique_ptr<int>&& obj) {set.insert(std::move(obj));}

std::unique_ptr根据定义没有复制构造函数。它确实有一个move构造函数。但是你在这里的唯一指针是一个常量,所以move构造函数不能被称为

最新更新