【发布时间】:2015-10-11 16:17:03
【问题描述】:
我在 1990 年参加了我的第一个 C++ 课程,早在您出现新奇的异常、STL 和诸如此类之前。现在我正在编写一个自定义 C++ 容器,我决定以此为契机学习一些 C++11 技术和概念,尤其是 unique_ptr。不幸的是,在插入元素时,我在移动语义上遇到了一些问题(我认为)。这是我试图编译的代码的一个非常精简的版本:
#include <vector>
#include <memory>
struct Key {
int k_;
Key() : k_(0){};
explicit Key(int k) : k_(k){};
Key(const Key &o) : k_(o.k_) {}
Key(Key &&o) { k_ = std::move(o.k_); }
Key &operator=(const Key &o) {
k_ = o.k_;
return *this;
}
Key &operator=(Key &&o) {
k_ = std::move(o.k_);
return *this;
}
int get() const { return k_; }
};
template <class T> class CustomContainer {
public:
typedef std::pair<Key, std::unique_ptr<Key>> Record;
CustomContainer() {}
~CustomContainer(){};
bool insert(const Record &record) {
objects.emplace_back(std::move(record));
return true;
}
std::vector<Record> objects;
};
int main() {
CustomContainer<Key> q;
q.insert(CustomContainer<Key>::Record(Key(1), std::unique_ptr<Key>(new Key(1))));
}
我正在插入一个指向 Key 对象的指针以保持代码简单。在我的实际应用中,Key 稍微复杂一点,T 不是 Key,而 Custom 容器的成员函数也多得多,但这足以突出问题。当我在向量中只有一个 unique_ptr 对象时,一切似乎都运行良好。一旦我添加了这对,我得到:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/ext/new_allocator.h:120:23: error: call to
implicitly-deleted copy constructor of 'std::pair<Key, std::unique_ptr<Key, std::default_delete<Key> > >'
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
.
.
.
simple.cc:33:13: note: in instantiation of function template specialization 'std::vector<std::pair<Key,
std::unique_ptr<Key, std::default_delete<Key> > >, std::allocator<std::pair<Key, std::unique_ptr<Key,
std::default_delete<Key> > > > >::emplace_back<const std::pair<Key, std::unique_ptr<Key,
std::default_delete<Key> > > >' requested here
objects.emplace_back(std::move(record));
^
simple.cc:41:5: note: in instantiation of member function 'CustomContainer<Key>::insert' requested here
q.insert(CustomContainer<Key>::Record(Key(1), std::unique_ptr<Key>(new Key(1))));
我用自定义类而不是一对尝试了同样的事情,得到了同样的错误。无论我添加多少 std::move(),我似乎都无法让编译器调用移动构造函数而不是复制构造函数。我错过了什么?
【问题讨论】:
-
你不能从
const的东西上移开。 -
我现在感觉很蠢。是的,就是这样。谢谢,克雷克。如果您想将其添加为正式答案,我很乐意接受。
标签: c++ c++11 move unique-ptr