为什么 insert in std::unordered_set 调用复制构造函数?
why does insert in std::unordered_set call the copy constructor?
我有 std::unordered_set 个指针。如果我这样做
int main()
{
std::unordered_set<std::unique_ptr<int>> set;
set.insert(std::make_unique(3));
}
一切正常,插入调用移动构造函数(我认为)。但是我有一个不同的情况类似于下面的代码
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)
它归结为一些基本的东西:根据定义,你不能移动一个常量对象。 “移动”基本上是指从被移出的对象中撕掉内脏,然后将所有内脏推入新的、被移动到的对象中(以最有效的方式,以外科医生的精确度)。如果移出的对象是 const
,则不能这样做。这是碰不得的。它必须保持其原始的原始状态。
如果参数是右值引用,你应该可以这样做:
void add(std::unique_ptr<int>&& obj) {set.insert(std::move(obj));}
std::unique_ptr 根据定义没有复制构造函数。它确实有一个移动构造函数。但是你这里的唯一指针是一个const,所以不能调用move构造函数
我有 std::unordered_set 个指针。如果我这样做
int main()
{
std::unordered_set<std::unique_ptr<int>> set;
set.insert(std::make_unique(3));
}
一切正常,插入调用移动构造函数(我认为)。但是我有一个不同的情况类似于下面的代码
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)
它归结为一些基本的东西:根据定义,你不能移动一个常量对象。 “移动”基本上是指从被移出的对象中撕掉内脏,然后将所有内脏推入新的、被移动到的对象中(以最有效的方式,以外科医生的精确度)。如果移出的对象是 const
,则不能这样做。这是碰不得的。它必须保持其原始的原始状态。
如果参数是右值引用,你应该可以这样做:
void add(std::unique_ptr<int>&& obj) {set.insert(std::move(obj));}
std::unique_ptr 根据定义没有复制构造函数。它确实有一个移动构造函数。但是你这里的唯一指针是一个const,所以不能调用move构造函数